UISearchController仅在搜索按钮单击时更新

Cha*_*lie 6 ios swift uisearchcontroller

我有一个UISearchController,配置为搜索非常大的数据.因此,当我在搜索栏中输入时,实际输入我的搜索需要很长时间.它与搜索字段中的每个字符条目执行搜索比较,这非常慢.

我想知道如何解决这个问题.我的想法是:

  1. 只有在用户完成输入后才能执行搜索并点击搜索按钮
  2. 在后台线程上执行搜索,释放主线程以进行键盘输入

我想使用方法1, 但我似乎无法弄清楚如何使用新的UISearchController执行此操作.

以下是我的相关项目代码:

class AirportSearchTBVC: UITableViewController, UISearchResultsUpdating{
var airportData = [Dictionary<String, String>]()
var filteredData = [Dictionary<String, String>]()
var searchController = UISearchController()
override func viewDidLoad() {
    super.viewDidLoad()


    searchController = UISearchController(searchResultsController: nil)
    searchController.searchResultsUpdater = self

    searchController.dimsBackgroundDuringPresentation = false

    searchController.searchBar.sizeToFit()
    tableView.tableHeaderView = searchController.searchBar

    definesPresentationContext = true


    searchController.hidesNavigationBarDuringPresentation = false

    self.tableView.reloadData()
}

func updateSearchResultsForSearchController(searchController: UISearchController) {

    filteredData = []

    let searchPredicate = NSPredicate(format: "SELF CONTAINS[cd] %@", searchController.searchBar.text!)
    let array = (airportData as NSArray).filteredArrayUsingPredicate(searchPredicate)

    filteredData = array as! [Dictionary<String, String>]

    self.tableView.reloadData()

}
Run Code Online (Sandbox Code Playgroud)

奖金问题 如果我搜索字符串,如果字符串不完全匹配,它似乎不会返回任何结果.例如:"orida"没有找到"佛罗里达".是不是我的搜索谓词应该使用CONTAINS找到它?

更新 此代码几乎可以工作,但它基本上会在后台线程中抛出一堆东西,然后通过它进行调整.键盘现在很生动,但是如果我在快速更改文本字段中的内容同时解除并重新进入搜索栏,它似乎会崩溃...

func updateSearchResultsForSearchController(searchController: UISearchController) {
    appDel.backgroundThread(background: {
        self.filteredData.removeAll(keepCapacity: false)

        let searchPredicate = NSPredicate(format: "SELF CONTAINS[cd] %@", searchController.searchBar.text!)
        let array = (self.airportData as NSArray).filteredArrayUsingPredicate(searchPredicate)

        self.filteredData = array as! [Dictionary<String, String>]
        },
        completion: {

            dispatch_async(dispatch_get_main_queue()) {
                    self.tableView.reloadData()
            }

    });






}
Run Code Online (Sandbox Code Playgroud)

更新2 在玩了一下之后,我能够通过等待searchBar.text长度> = 3个字符以及确保字符数在updateSearchResultsForSearchController的1秒内没有变化来使它工作得相当不错:被叫.这些组合以及集成搜索按钮执行命令应该可以解决我的问题.

func updateSearchResultsForSearchController(searchController: UISearchController) {
    let startCount = searchController.searchBar.text!.length
    delay(1) {
    if searchController.searchBar.text!.length >= 3 && searchController.searchBar.text!.length == startCount{
        self.view.addSubview(self.progressHud)
        self.appDel.backgroundThread(background: {
            self.filteredData.removeAll(keepCapacity: false)

            let searchPredicate = NSPredicate(format: "SELF CONTAINS[cd] %@", searchController.searchBar.text!)
            let array = (self.airportData as NSArray).filteredArrayUsingPredicate(searchPredicate)

            self.filteredData = array as! [Dictionary<String, String>]
            },
            completion: {
                dispatch_async(dispatch_get_main_queue()) {
                    self.tableView.reloadData()
                    self.progressHud.removeFromSuperview()
                }



        });
    }
    }





}
    func delay(delay:Double, closure:()->()) {
        dispatch_after(
            dispatch_time(
                DISPATCH_TIME_NOW,
                Int64(delay * Double(NSEC_PER_SEC))
            ),
            dispatch_get_main_queue(), closure)
    }
Run Code Online (Sandbox Code Playgroud)

pbu*_*h25 9

您可以使用委托方法searchBarSearchButtonPressed:监视按下搜索按钮的时间.执行此委托方法时设置一个标志,然后在您的searchBarTextDidChange:方法中,您可以检查此标志以查看是否应执行搜索.当然,这只会在用户按下搜索后进行搜索,大多数人都希望在打字时看到发生的事情.


ksh*_*erd 6

如果您只想在用户单击"搜索"按钮时执行搜索 - 这对于更大和更慢的访问数据集来说似乎既合理又合理,您可以这样做:

class AirportSearchTBVC: UITableViewController, UISearchResultsUpdating{
var airportData = [Dictionary<String, String>]()
var filteredData = [Dictionary<String, String>]()
var searchController = UISearchController()
override func viewDidLoad() {
    super.viewDidLoad()


    searchController = UISearchController(searchResultsController: nil)
    searchController.searchResultsUpdater = self
    searchController.searchBar.delegate = self

    searchController.dimsBackgroundDuringPresentation = false

    searchController.searchBar.sizeToFit()
    tableView.tableHeaderView = searchController.searchBar

    definesPresentationContext = true


    searchController.hidesNavigationBarDuringPresentation = false

    self.tableView.reloadData()
}

func searchBarSearchButtonClicked(searchBar: UISearchBar) {
    filteredData = []

    let searchPredicate = NSPredicate(format: "SELF CONTAINS[cd] %@", searchController.searchBar.text!)
    let array = (airportData as NSArray).filteredArrayUsingPredicate(searchPredicate)

    filteredData = array as! [Dictionary<String, String>]

    self.tableView.reloadData()

}
func updateSearchResultsForSearchController(searchController: UISearchController) {

}
Run Code Online (Sandbox Code Playgroud)

关键区别在于设置searchController.searchBar.delegate = self,并将搜索代码放在searchBarSearchButtonClicked函数中,而不是updateSearchResultsForSearchController - 它现在应该什么也不做.我为任何错误道歉,我使用Xcode v7.0.1 Objective-C测试了这段代码,然后转换了这些更改.