键入时无需按下“搜索”按钮,如何刷新UISearchBar搜索结果?有什么本机的方法吗?

时间:2019-05-12 23:04:22

标签: swift uisearchbar

我正在开发一个非常简单的应用程序,例如Notes,并且具有searchBar。但是,每次我要搜索时,都必须在searchBar中键入一些内容,然后按Search(搜索)按钮。键入时是否可以进行搜索?键入一个字符-刷新表,键入另一个-再次刷新表。

这是我的扩展名的样子。 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()
}

3 个答案:

答案 0 :(得分:0)

我假设“ 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()
        }
    }
}

答案 1 :(得分:0)

可以连接textDidChange,但是有一些缺点。例如:如果用户输入速度太快,那么当这些过滤和查询操作不是很重要时,您将查询服务器(如果过滤后的结果是从服务器获取的)或过滤阵列(如果结果是本地的)太多次因为用户仍在输入。

相反,您可以使用RxSwift。这是一个了不起的库,有很多用途。想法是将用户的键入视为事件流。然后,使用RxSwift,可以在该事件流上应用一些逻辑。例如,等待下一次查询/筛选操作需要多少时间,才能具有不同的价值以及许多其他操作。

看看this示例。

答案 2 :(得分:0)

我将代码从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()
    }
}