尝试在 Swift 中使用 UISearchResult。如何实现过滤?
Posted
技术标签:
【中文标题】尝试在 Swift 中使用 UISearchResult。如何实现过滤?【英文标题】:Trying to use UISearchResult in Swift. How to implement filtering? 【发布时间】:2016-04-06 10:30:00 【问题描述】:我正在尝试在我的应用中创建露营地搜索功能。我希望用户能够在搜索栏中输入内容,并让显示的露营地过滤器列表与他们输入的内容相匹配。现在用户点击一个按钮来调出 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 函数需要做什么?
【问题讨论】:
【参考方案1】:您需要使用在搜索栏中输入的文本 (searchController.searchBar.text
) 过滤您的数据源 (campgrounds
),然后使用过滤后的数据重新加载您的表格视图。
如果要将数据源保留为计算属性,则需要定义一个新变量来保存过滤后的露营地数组(见下文)。然后,您必须引入检查以确定使用哪个数据源,具体取决于搜索控制器是否处于活动状态。
或者,您可以使用单个数据源,它会根据需要返回一组过滤或未过滤的露营地。
请注意,您需要import 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 开头的项目。此外,当我单击搜索栏时,该列表会消失。代码的哪一部分控制这个? 重新准确性——示例代码中使用的过滤条件是设施名称是否包含搜索文本,而不是设施名称是否以搜索文本开头。如果您更喜欢后者,可以将rangeOfString()
替换为hasPrefix()
。
重新消失的列表——这可能是由示例代码中检查self.searchController.active
的部分控制的(只要你点击搜索栏就是这样)。我已经编辑了这些部分以添加检查以确保搜索栏文本不为空。这应该可以防止原始露营地列表消失,直到在搜索栏中输入一些文本。以上是关于尝试在 Swift 中使用 UISearchResult。如何实现过滤?的主要内容,如果未能解决你的问题,请参考以下文章
尝试在 Swift 中使用来自 CKRecord 的原始数据形式
尝试在启动应用程序时使用 Swift 在 Xcode 中查找用户位置但出现可选错误?
尝试在具有 SpriteKit 场景 (SWIFT) 的 didMoveToView 中使用 waitForDuration 延迟生成节点但不工作