美文网首页
SearchViewController 示例

SearchViewController 示例

作者: _浅墨_ | 来源:发表于2022-11-11 10:49 被阅读0次

    在 Market 项目中发现一个漂亮的搜索页面,记录一下。

    SearchViewController.swift:

    import UIKit
    import NVActivityIndicatorView
    import EmptyDataSet_Swift
    
    class SearchViewController: UIViewController {
    
        //MARK: - IBOutlets
        
        @IBOutlet weak var searchOptionsView: UIView!
        @IBOutlet weak var tableView: UITableView!
        @IBOutlet weak var searchTextField: UITextField!
        @IBOutlet weak var searchButtonOutlet: UIButton!
        
        //MARK: - Vars
        var searchResults: [Item] = []
        
        var activityIndicator: NVActivityIndicatorView?
        
        
        //MARK: - View Lifecycle
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            tableView.tableFooterView = UIView()
            
            searchTextField.addTarget(self, action: #selector(self.textFieldDidChange(_:)), for: UIControl.Event.editingChanged)
            
            tableView.emptyDataSetDelegate = self
            tableView.emptyDataSetSource = self
        }
        
        override func viewDidAppear(_ animated: Bool) {
            super.viewDidAppear(animated)
            
            activityIndicator = NVActivityIndicatorView(frame: CGRect(x: self.view.frame.width / 2 - 30, y: self.view.frame.height / 2 - 30, width: 60, height: 60), type: .ballPulse, color: #colorLiteral(red: 0.9998469949, green: 0.4941213727, blue: 0.4734867811, alpha: 1), padding: nil)
        }
        
        
        //MARK: - IBActions
        
        @IBAction func showSearchBarBattonPressed(_ sender: Any) {
            
            dismissKeyboard()
            showSearchField()
        }
        
        @IBAction func searchButtonPressed(_ sender: Any) {
            
            if searchTextField.text != "" {
                
                searchInFirebase(forName: searchTextField.text!)
                emptyTextField()
                animateSearchOptionsIn()
                dismissKeyboard()
            }
            
        }
        
        //MARK: - Search database
    
        private func searchInFirebase(forName: String) {
            
            showLoadingIndicator()
            
            searchAlgolia(searchString: forName) { (itemIds) in
                
                downloadItems(itemIds) { (allItems) in
                    
                    self.searchResults = allItems
                    self.tableView.reloadData()
                    
                    self.hideLoadingIndicator()
                }
            }
        }
    
        
        //MARK: - Helpers
        
        private func emptyTextField() {
            searchTextField.text = ""
        }
        
        private func dismissKeyboard() {
            self.view.endEditing(false)
        }
        
        @objc func textFieldDidChange (_ textField: UITextField) {
            
            searchButtonOutlet.isEnabled = textField.text != ""
            
            if searchButtonOutlet.isEnabled {
                searchButtonOutlet.backgroundColor = #colorLiteral(red: 0.9998469949, green: 0.4941213727, blue: 0.4734867811, alpha: 1)
            } else {
                disableSearchButton()
            }
            
        }
        
        
        private func disableSearchButton() {
            searchButtonOutlet.isEnabled = false
            searchButtonOutlet.backgroundColor = #colorLiteral(red: 0.6666666865, green: 0.6666666865, blue: 0.6666666865, alpha: 1)
        }
    
        private func showSearchField() {
            
            disableSearchButton()
            emptyTextField()
            animateSearchOptionsIn()
        }
        
        //MARK: - Animations
        
        private func animateSearchOptionsIn() {
            
            UIView.animate(withDuration: 0.5) {
                self.searchOptionsView.isHidden = !self.searchOptionsView.isHidden
            }
        }
    
        //MARK: - Activity indicator
        
        private func showLoadingIndicator() {
            
            if activityIndicator != nil {
                self.view.addSubview(activityIndicator!)
                activityIndicator!.startAnimating()
            }
        }
    
        
        private func hideLoadingIndicator() {
            if activityIndicator != nil {
                activityIndicator!.removeFromSuperview()
                activityIndicator!.stopAnimating()
            }
            
        }
        
        private func showItemView(withItem: Item) {
            
            let itemVC = UIStoryboard.init(name: "Main", bundle: nil).instantiateViewController(identifier: "itemView") as! ItemViewController
            
            itemVC.item = withItem
            
            self.navigationController?.pushViewController(itemVC, animated: true)
        }
        
    }
    
    
    extension SearchViewController: UITableViewDataSource, UITableViewDelegate {
        
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            
            return searchResults.count
        }
        
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            
            let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! ItemTableViewCell
            
            cell.generateCell(searchResults[indexPath.row])
            
            return cell
            
        }
        
        //MARK: - UITableView Delegate
        
        func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
            
            tableView.deselectRow(at: indexPath, animated: true)
            
            showItemView(withItem: searchResults[indexPath.row])
        }
    
    }
    
    
    extension SearchViewController: EmptyDataSetSource, EmptyDataSetDelegate {
        
        func title(forEmptyDataSet scrollView: UIScrollView) -> NSAttributedString? {
            
            return NSAttributedString(string: "No itmes to display!")
        }
        
        func image(forEmptyDataSet scrollView: UIScrollView) -> UIImage? {
            return UIImage(named: "emptyData")
        }
        
        func description(forEmptyDataSet scrollView: UIScrollView) -> NSAttributedString? {
            return NSAttributedString(string: "Please check back later")
        }
        
        func buttonImage(forEmptyDataSet scrollView: UIScrollView, for state: UIControl.State) -> UIImage? {
            return UIImage(named: "search")
        }
        
        func buttonTitle(forEmptyDataSet scrollView: UIScrollView, for state: UIControl.State) -> NSAttributedString? {
            return NSAttributedString(string: "Start searching...")
        }
        
        
        func emptyDataSet(_ scrollView: UIScrollView, didTapButton button: UIButton) {
            
            showSearchField()
        }
    }
    
    

    自定义 ItemTableViewCell:

    import UIKit
    
    class ItemTableViewCell: UITableViewCell {
    
        //MARK: IBOutlets
        @IBOutlet weak var itemImageView: UIImageView!
        @IBOutlet weak var nameLabel: UILabel!
        @IBOutlet weak var descriptionLabel: UILabel!
        @IBOutlet weak var priceLabel: UILabel!
        
        
        override func awakeFromNib() {
            super.awakeFromNib()
        }
    
        override func setSelected(_ selected: Bool, animated: Bool) {
            super.setSelected(selected, animated: animated)
        }
        
        func generateCell(_ item: Item) {
            
            nameLabel.text = item.name
            descriptionLabel.text = item.description
            priceLabel.text = convertToCurrency(item.price)
            priceLabel.adjustsFontSizeToFitWidth = true
            
            if item.imageLinks != nil && item.imageLinks.count > 0 {
                
                downloadImages(imageUrls: [item.imageLinks.first!]) { (images) in
                    self.itemImageView.image = images.first as? UIImage
                }
            }
        }
    
    }
    

    自定义 Item:

    import Foundation
    import UIKit
    //import InstantSearchClient
    
    class Item {
        
        var id: String!
        var categoryId: String!
        var name: String!
        var description: String!
        var price: Double!
        var imageLinks: [String]!
        
        init() {
        }
        
        init(_dictionary: NSDictionary) {
            
            id = _dictionary[kOBJECTID] as? String
            categoryId = _dictionary[kCATEGORYID] as? String
            name = _dictionary[kNAME] as? String
            description = _dictionary[kDESCRIPTION] as? String
            price = _dictionary[kPRICE] as? Double
            imageLinks = _dictionary[kIMAGELINKS] as? [String]
        }
    }
    
    
    //MARK: Save items func
    
    func saveItemToFirestore(_ item: Item) {
        
        FirebaseReference(.Items).document(item.id).setData(itemDictionaryFrom(item) as! [String : Any])
    }
    
    
    //MARK: Helper functions
    
    func itemDictionaryFrom(_ item: Item) -> NSDictionary {
        
        return NSDictionary(objects: [item.id, item.categoryId, item.name, item.description, item.price, item.imageLinks], forKeys: [kOBJECTID as NSCopying, kCATEGORYID as NSCopying, kNAME as NSCopying, kDESCRIPTION as NSCopying, kPRICE as NSCopying, kIMAGELINKS as NSCopying])
    }
    
    
    //MARK: Download Func
    func downloadItemsFromFirebase(_ withCategoryId: String, completion: @escaping (_ itemArray: [Item]) -> Void) {
        
        var itemArray: [Item] = []
        
        FirebaseReference(.Items).whereField(kCATEGORYID, isEqualTo: withCategoryId).getDocuments { (snapshot, error) in
            
            guard let snapshot = snapshot else {
                completion(itemArray)
                return
            }
            
            if !snapshot.isEmpty {
                
                for itemDict in snapshot.documents {
                    
                    itemArray.append(Item(_dictionary: itemDict.data() as NSDictionary))
                }
            }
            
            completion(itemArray)
        }
        
    }
    
    func downloadItems(_ withIds: [String], completion: @escaping (_ itemArray: [Item]) ->Void) {
        
        var count = 0
        var itemArray: [Item] = []
        
        if withIds.count > 0 {
            
            for itemId in withIds {
    
                FirebaseReference(.Items).document(itemId).getDocument { (snapshot, error) in
                    
                    guard let snapshot = snapshot else {
                        completion(itemArray)
                        return
                    }
    
                    if snapshot.exists {
    
                        itemArray.append(Item(_dictionary: snapshot.data()! as NSDictionary))
                        count += 1
                    }
                    
                    if count == withIds.count {
                        completion(itemArray)
                    }
                    
                }
            }
        } else {
            completion(itemArray)
        }
    }
    

    相关文章

      网友评论

          本文标题:SearchViewController 示例

          本文链接:https://www.haomeiwen.com/subject/lhoxxdtx.html