在Swift中智能搜索Parse用户名不起作用 [英] Smart-search for Parse Usernames in Swift not working

查看:112
本文介绍了在Swift中智能搜索Parse用户名不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在我的iOS应用中进行智能搜索,以便当用户在UISearchBar中键入字符时,结果会自动在搜索栏下方的表格视图中更新。出于某种原因,当我在搜索栏中键入一个字符时,不会调用带有textDidChange的searchBar函数。在输入2个字符后调用它。所以我的搜索结果总是落后于实际输入搜索栏的一步。而且似乎每次都会调用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.

这应该为你完成工作

干杯,
罗素

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中智能搜索Parse用户名不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆