UISearchBar 不在 TableView 中查找信息

Posted

技术标签:

【中文标题】UISearchBar 不在 TableView 中查找信息【英文标题】:UISearchBar not looking for information in TableView 【发布时间】:2019-06-07 06:55:21 【问题描述】:

我尝试从firebase 获取数据并显示在tableView 中。一切都是好的。但我需要使用UISearchBar 在 tableView 中搜索。我应该解决两个问题。

1) 当我开始输入时,我的tableView 消失了。里面的所有信息都没有显示出来

2) 当我删除UISearchBar 中的所有内容时,什么也没有出现。

import UIKit
import SPStorkController
import Firebase

class FoodViewController: UIViewController 

    override var preferredStatusBarStyle: UIStatusBarStyle  return .lightContent 
    let tableView = UITableView()
    var foods = [FoodModel]()
    var searchedFoods = [String]()
    var searching = false

    override func viewDidLoad() 
        super.viewDidLoad()

        fetchFoods()

        self.modalPresentationCapturesStatusBarAppearance = true
        self.view.backgroundColor = UIColor.white
        let controller = UIViewController()

        self.tableView.delegate = self
        self.tableView.dataSource = self
        self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")            

        self.view.addSubview(self.tableView)

        tableView.delegate = self
        tableView.dataSource = self

        let searchBar = UISearchBar(frame: CGRect(x: 0, y: 5, width: 350, height: 40))
        searchBar.searchBarStyle = .minimal
        searchBar.delegate = self

        self.view.addSubview(searchBar)            
    

    override func viewWillLayoutSubviews() 
        super.viewWillLayoutSubviews()
        self.updateLayout(with: self.view.frame.size)
    

    func updateLayout(with size: CGSize) 
        self.tableView.frame = CGRect.init(x: 0, y: 45, width: size.width, height: 400)            
    

    func fetchFoods() 
        Database.database().reference().child("food").observe(.childAdded)  (snapshot) in
            if let dict = snapshot.value as? [String: AnyObject] 
                let newTitle = dict["title"] as! String
                let exCell = FoodModel(title: newTitle)
                self.foods.append(exCell)
                DispatchQueue.main.async 
                    self.tableView.reloadData()                        
                
                            
                    
    


extension FoodViewController: UITableViewDataSource  

   func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)

        if searching 
            cell.textLabel?.text = searchedFoods[indexPath.row]
         else 
            let food = foods[indexPath.item]
            cell.textLabel?.text = food.title
        
        return cell
    

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        if searching 
            return searchedFoods.count
         else 
            return foods.count
        
    

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) 
    


extension FoodViewController: UITableViewDelegate 

    func scrollViewDidScroll(_ scrollView: UIScrollView) 
        if scrollView == self.tableView 
            SPStorkController.scrollViewDidScroll(scrollView)
        
    


extension FoodViewController: UISearchBarDelegate 

    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) 
        //searchedFoods = foods.filter($0.lowercased().prefix(searchText.count) == searchText.lowercased())
        searching = true
        tableView.reloadData()
    

    func searchBarCancelButtonClicked(_ searchBar: UISearchBar) 
        searching = false
        searchBar.text = ""
        tableView.reloadData()
            
`

这是我的模特

class FoodModel 

    var title = String()

    init (title: String) 

        self.title = title
    

【问题讨论】:

为什么 searchedFoods 是一个字符串数组?你不给它分配字符串 @Scriptable 我尝试让 searchedFoods = [FoodModel]() 但这没有帮助。告诉我要重拍什么 您正在执行的过滤器将返回 [FoodModel] @Scriptable 请写一个代码。我不知道如何解决 你已经有了代码:searchedFoods = foods.filter($0.lowercased().prefix(searchText.count) == searchText.lowercased())。将 searchedFoods 更改为 [FoodModel]() 并尝试 【参考方案1】:

searchedFoods 应该是一个对象数组,与主要食物列表相同。

我认为你只需要更新你的过滤器

所以把searchedFoods改成[FoodModel]()

然后将过滤器更改为:

searchedFoods = foods.filter( $0.title.lowercased().prefix(searchText.count) == searchText.lowercased() )

【讨论】:

【参考方案2】:

您必须同时使用相同类型的数据源数组和过滤后的数组

var searchedfoods = [FoodModel]()

你必须这样实现textDidChange,如果搜索文本为空,它会取消搜索

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) 
    if searchText.isEmpty 
        searchedFoods.removeAll()
        searching = false
     else 
        searchedFoods = foods.filter $0.title.range(of: searchText, options: [.caseInsensitive, .anchored]) != nil 
        searching = true
    
    tableView.reloadData()

您用于过滤项目的 API 非常繁琐且不必要的昂贵。 range(of:options: 指定适当的选项效率更高。 caseInsensitive 避免多次调用 lowercased().anchored 总是从字符串的开头搜索。

【讨论】:

以上是关于UISearchBar 不在 TableView 中查找信息的主要内容,如果未能解决你的问题,请参考以下文章

UISearchBar、textDidChange 事件、MultipleNSUrlConnection、tableView 崩溃

包含 TableView 的 UIViewController 中的 UISearchBar 问题

将 UISearchBar 作为子视图添加到 tableView 标题中

使用 TableView 和刷新控件将按钮添加到 UISearchBar

如何将 UISearchBar 添加到同一 UIViewController 中的两个 TableView

如何以编程方式将 UISearchBar 添加到我的 tableView 中?