在 Swift 中智能搜索解析用户名不起作用 [英] Smart-search for Parse Usernames in Swift not working
问题描述
我正在尝试在我的 iOS 应用程序中进行智能搜索,以便当用户在 UISearchBar 中键入一个字符时,结果会在搜索栏下方的 tableview 中自动更新.出于某种原因,当我在搜索栏中键入字符时,不会调用带有 textDidChange 的 searchBar 函数.在输入 2 个字符后调用它.因此,我的搜索结果始终比实际输入到搜索栏中的内容晚 1 步.而且似乎每次都调用 search() 函数两次.有任何想法吗?
I'm trying to have a smart-search in my iOS app so that when a user types a character into a UISearchBar, the results automatically update in the tableview below the searchbar. For some reason, the searchBar function with textDidChange isn't called when I type a character into the search bar. It's called after 2 characters are typed. So my search results are always 1 step behind what's actually typed into the search bar. And it also seems like the search() function is being called twice every time. Any ideas?
//FUNC: search
func search(searchText: String? = nil){
if searchText == nil || searchText == "" {
println("No users found.")
} else {
var query = PFUser.query()
//MAKE CASE INSENSTIVE
query!.whereKey("username", containsString: searchText!)
query!.findObjectsInBackgroundWithBlock { (results, error) -> Void in
if error != nil {
println(error)
} else {
if let res = results {
self.data = res as? [PFUser]
}
}
}
}
self.tableView.reloadData()
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! UITableViewCell
let user = data[indexPath.row] as! PFUser
let username = user.username
println(username)
cell.textLabel?.text = username
return cell
}
func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
search(searchText: searchText)
searchActive = false;
}
推荐答案
您需要实现 UISearchResultsUpdating 协议来实现这一点.它使用 UISearchController(在 iOS 8 中引入),必须以编程方式而不是通过故事板添加,但别担心,它非常简单.
You will want to implement the UISearchResultsUpdating protocol to achieve this. It uses a UISearchController (introduced in iOS 8) which has to be added programmatically instead of through the storyboard, but don't worry, it's pretty straight-forward.
这应该可以为您完成工作
This should get the job done for you
干杯,罗素
class YourTableViewController: UITableViewController, UISearchBarDelegate, UISearchResultsUpdating {
var searchUsers: [PFUser] = [PFUser]()
var userSearchController = UISearchController()
var searchActive: Bool = false
// MARK: - Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
self.userSearchController = UISearchController(searchResultsController: nil)
self.userSearchController.dimsBackgroundDuringPresentation = true
// This is used for dynamic search results updating while the user types
// Requires UISearchResultsUpdating delegate
self.userSearchController.searchResultsUpdater = self
// Configure the search controller's search bar
self.userSearchController.searchBar.placeholder = "Search for a user"
self.userSearchController.searchBar.sizeToFit()
self.userSearchController.searchBar.delegate = self
self.definesPresentationContext = true
// Set the search controller to the header of the table
self.tableView.tableHeaderView = self.userSearchController.searchBar
}
// MARK: - Parse Backend methods
func loadSearchUsers(searchString: String) {
var query = PFUser.query()
// Filter by search string
query.whereKey("username", containsString: searchString)
self.searchActive = true
query.findObjectsInBackgroundWithBlock { (objects: [AnyObject]?, error: NSError?) -> Void in
if (error == nil) {
self.searchUsers.removeAll(keepCapacity: false)
self.searchUsers += objects as! [PFUser]
self.tableView.reloadData()
} else {
// Log details of the failure
println("search query error: (error) (error!.userInfo!)")
}
self.searchActive = false
}
}
// MARK: - Search Bar Delegate Methods
func searchBarSearchButtonClicked(searchBar: UISearchBar) {
// Force search if user pushes button
let searchString: String = searchBar.text.lowercaseString
if (searchString != "") {
loadSearchUsers(searchString)
}
}
func searchBarCancelButtonClicked(searchBar: UISearchBar) {
// Clear any search criteria
searchBar.text = ""
// Force reload of table data from normal data source
}
// MARK: - UISearchResultsUpdating Methods
// This function is used along with UISearchResultsUpdating for dynamic search results processing
// Called anytime the search bar text is changed
func updateSearchResultsForSearchController(searchController: UISearchController) {
let searchString: String = searchController.searchBar.text.lowercaseString
if (searchString != "" && !self.searchActive) {
loadSearchUsers(searchString)
}
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if (self.userSearchController.active) {
return self.searchUsers.count
} else {
// return whatever your normal data source is
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("userCell") as! UserCell
if (self.userSearchController.active && self.searchUsers.count > indexPath.row) {
// bind data to the search results cell
} else {
// bind data from your normal data source
}
return cell
}
// MARK: - UITableViewDelegate
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
if (self.userSearchController.active && self.searchUsers.count > 0) {
// Segue or whatever you want
} else {
// normal data source selection
}
}
}
这篇关于在 Swift 中智能搜索解析用户名不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!