【问题标题】:How to refresh UISearchBar search results when type without need to press "Search" button? Is there any native way?键入时如何刷新 UISearchBar 搜索结果而无需按“搜索”按钮?有什么本土方法吗?
【发布时间】:2019-06-15 19:31:21
【问题描述】:

我正在开发一个非常简单的应用程序,例如 Notes,并且我有 searchBar。但是,每次我想搜索时,我都必须在 searchBar 中输入一些内容并按下搜索按钮。有没有办法在我输入时进行搜索?键入一个字符 - 刷新表格,键入另一个字符 - 再次刷新表格。

这就是我的扩展程序的样子。 loadData() 是一个从 CoreData 加载数据到 tobleView 的函数。

extension ViewController: UISearchBarDelegate {

func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
    let request : NSFetchRequest<Note> = Note.fetchRequest()

    request.predicate = NSPredicate(format: "text CONTAINS[c] %@", searchBar.text!)

    request.sortDescriptors = [NSSortDescriptor(key: "text", ascending: true)]

    loadData(with: request)
}

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
    if searchBar.text?.count == 0 {
        getNotes()
        DispatchQueue.main.async {
            searchBar.resignFirstResponder()
        }
    } else {
        self.tableView.reloadData()
    }
}

func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
    searchBar.text = ""
    searchBar.endEditing(true)

    getNotes()
}

【问题讨论】:

    标签: swift uisearchbar


    【解决方案1】:

    我假设“getNotes()”是您必须查询用户保存的笔记的方法。您应该/可以做的是将完成处理程序添加到 getNotes() 和一个接受字符串的参数。使用委托方法 textDidChange (您已经符合)您可以执行类似的操作...

        func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        guard let txt = searchText.trimmingCharacters(in: .whitespacesAndNewlines), !txt.isEmpty else {return}
    
        getNotes(searchText: txt) { (results) in
            // Set your data source with new results
            self.src = results
            // Reload collection
            DispatchQueue.main.async {
                self.collectionView.reload()
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      对 textDidChange 有一个钩子会起作用,但它有一些缺点。例如:如果用户输入速度太快,您将查询服务器(如果过滤结果是从服务器获取)或过滤数组(如果结果是本地的)太多次,而这些过滤和查询操作并不真正重要因为用户仍在输入。

      相反,您可以使用 RxSwift。这是一个了不起的图书馆,有很多用途。这个想法是将用户的输入视为事件流。然后使用 RxSwift,您可以对该事件流应用一些逻辑。例如,等待下一个查询/过滤操作、具有不同值和许多其他操作的时间。

      查看this 示例。

      【讨论】:

      • 关于您第一次查询服务器的次数过多,OP 可以通过搜索限制来规避这一点:在 textDidChange() 内创建一个 Timer 对象并等待一段时间(例如 0.5 秒) ,然后在计时器上调用invalidate() 将其重置。
      【解决方案3】:

      我将代码从 searchBarSearchButtonClicked() 函数转移到了 searchBar textDidChange() 函数。 现在它可以工作了,看起来像:

      func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
          if searchBar.text?.count == 0 {
              getNotes()
              DispatchQueue.main.async {
                  searchBar.resignFirstResponder()
              }
          } else {
              let request : NSFetchRequest<Note> = Note.fetchRequest()
              request.predicate = NSPredicate(format: "text CONTAINS[c] %@", searchBar.text!)
              request.sortDescriptors = [NSSortDescriptor(key: "text", ascending: true)]
      
              getNotes(with: request)
              self.tableView.reloadData()
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-07-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-11
        • 2012-03-31
        相关资源
        最近更新 更多