正在尝试在Swift中使用UISearchResult。如何实现过滤?

正在尝试在Swift中使用UISearchResult。如何实现过滤?,swift,search,filtering,uisearchcontroller,Swift,Search,Filtering,Uisearchcontroller,我正在尝试在我的应用程序中创建营地搜索功能。我希望用户能够在搜索栏中键入内容,并将显示的露营地过滤器列表与他们键入的内容相匹配。现在,一个用户点击一个按钮打开SearchCampgroundsViewController.swift。以下是我到目前为止在该文件中的代码: import UIKit class SearchCampgroundsViewController: UIViewController, UISearchResultsUpdating { let searchCo

我正在尝试在我的应用程序中创建营地搜索功能。我希望用户能够在搜索栏中键入内容,并将显示的露营地过滤器列表与他们键入的内容相匹配。现在,一个用户点击一个按钮打开SearchCampgroundsViewController.swift。以下是我到目前为止在该文件中的代码:

import UIKit

class SearchCampgroundsViewController: UIViewController, UISearchResultsUpdating {

    let searchController = UISearchController(searchResultsController: nil)

    @IBOutlet weak var tableView: UITableView!
    var campgrounds: [Campground]? {
       return DataProvider.sharedInstance.allCampground()
    }


    override func viewDidLoad() {
        super.viewDidLoad()

        searchController.searchResultsUpdater = self
        searchController.hidesNavigationBarDuringPresentation = false
        searchController.dimsBackgroundDuringPresentation = false
        self.tableView.tableHeaderView = searchController.searchBar
    }


    func updateSearchResultsForSearchController(searchController: UISearchController) {

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

extension SearchCampgroundsViewController: UITableViewDataSource {

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.campgrounds?.count ?? 0
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("campgroundCell")! as UITableViewCell
        cell.textLabel?.text = campgrounds?[indexPath.row].facilityName ?? "NO NAME FOR THIS FACILITY"
        return cell
    }
}

露营地列表在表视图中正确显示(列表约4000个项目),搜索栏正确显示在表的顶部。我可以在搜索栏中输入,但结果不会过滤。如何实现过滤?updateSearchResultsForSearchController函数需要什么

您需要使用输入到搜索栏中的文本(
searchController.searchBar.text
)过滤数据源(
campgrounds
),然后用过滤后的数据重新加载表视图

若您想将数据源保留为计算属性,则需要定义一个新变量来保存一个过滤后的营地数组(见下文)。然后,您必须引入检查,以根据搜索控制器是否处于活动状态来确定要使用的数据源

或者,您可以使用单个数据源,根据需要返回一个过滤或未过滤的营地数组

请注意,您需要
导入Foundation
才能使用
rangeOfString()

尝试以下几点:

import Foundation

/* ... */

var filtered: [Campground]?

func updateSearchResultsForSearchController(searchController: UISearchController) {        
    filtered = campgrounds?.filter {
        // True if facilityName contains search bar text (case-sensitive).
        $0.facilityName.rangeOfString(searchController.searchBar.text!) != nil
    }

    tableView.reloadData()
}

/* ... */

extension SearchCampgroundsViewController: UITableViewDataSource
{
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if searchController.active && !searchController.searchBar.text.isEmpty {
            return filtered?.count ?? 0
        }

        return campgrounds?.count ?? 0
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("campgroundCell")! as UITableViewCell

        if searchController.active && searchController.searchBar.text != "" {
            cell.textLabel?.text = filtered?[indexPath.row].facilityName ?? "NO NAME FOR THIS FACILITY"
        } else {
            cell.textLabel?.text = campgrounds?[indexPath.row].facilityName ?? "NO NAME FOR THIS FACILITY"
        }

        return cell
    }
}

谢谢你的回复。我实现了这个代码。它是过滤,虽然不是很准确。例如,如果我键入一个“D”,它仍然会在列表顶部显示以a开头的项目。此外,当我单击搜索栏时,列表将消失。代码的哪一部分控制了这一点?示例代码中使用的过滤标准是facilityName是否包含搜索文本,而不是facilityName是否以搜索文本开头。如果您喜欢后者,可以将
rangeOfsString()
替换为
hasPrefix()
。这可能是由示例代码中选中
self.searchController.active
的部分控制的(只要您点击搜索栏,就会出现这种情况)。我编辑了这些部分,添加了一个检查,以确保搜索栏文本不是空的。这样可以防止原始营地列表在搜索栏输入一些文本之前消失。