Select Filtered search results

前端 未结 1 2040
温柔的废话
温柔的废话 2020-12-10 23:42

Whenever I search in my app I get the correct results to display but when I tap on the cell I searched for it always plays the first index of the table before I do the searc

相关标签:
1条回答
  • 2020-12-11 00:19

    I think that the issue is that you are tracking whether you are searching or not yourself and manipulating the source data array.

    I have an example playground snippet I have used for some other answers which shows you how to do this more efficiently and has some handy helper functions to make it easier.


    I think the key parts of this that would be beneficial to you are:

    keep a seperate array just of search results, only used when search is active

    var filteredNames = [String]()
    

    Make sure that you adjust the count and rows used when searching or not

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if isFiltering() {
            return filteredNames.count
        } else {
            return names.count
        }
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell() // don't do this, i am for example.
    
        var name: String
        if isFiltering() {
            name = filteredNames[indexPath.row]
        } else {
            name = names[indexPath.row]
        }
    
        cell.textLabel?.text = name
        return cell
    }
    

    You can use the following helper functions to help you out.

    func searchBarIsEmpty() -> Bool {
        // Returns true if the text is empty or nil
        return searchController.searchBar.text?.isEmpty ?? true
    }
    
    func isFiltering() -> Bool {
        return searchController.isActive && !searchBarIsEmpty()
    }
    

    Full UISearchController Example (playground)

    import UIKit
    import PlaygroundSupport
    
    class ViewController: UITableViewController {
    
        let searchController = UISearchController(searchResultsController: nil)
    
        var names = [
            "John",
            "Terry",
            "Martin",
            "Steven",
            "Michael",
            "Thomas",
            "Jason",
            "Matthew"
        ]
        var filteredNames = [String]()
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            self.title = "Search Example"
    
            searchController.searchResultsUpdater = self
            searchController.obscuresBackgroundDuringPresentation = false
            searchController.searchBar.placeholder = "Search"
            navigationItem.searchController = searchController
            definesPresentationContext = true
        }
    
        override func numberOfSections(in tableView: UITableView) -> Int {
            return 1
        }
    
        override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            if isFiltering() {
                return filteredNames.count
            } else {
                return names.count
            }
        }
    
        override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = UITableViewCell() // don't do this, i am for example.
    
            var name: String
            if isFiltering() {
                name = filteredNames[indexPath.row]
            } else {
                name = names[indexPath.row]
            }
    
            cell.textLabel?.text = name
            return cell
        }
    
        func searchBarIsEmpty() -> Bool {
            // Returns true if the text is empty or nil
            return searchController.searchBar.text?.isEmpty ?? true
        }
    
        func isFiltering() -> Bool {
            return searchController.isActive && !searchBarIsEmpty()
        }
    
        func filterContentForSearchText(_ searchText: String, scope: String = "All") {
            filteredNames = names.filter({( name : String) -> Bool in
                return name.lowercased().contains(searchText.lowercased())
            })
    
            tableView.reloadData()
        }
    }
    
    extension ViewController: UISearchResultsUpdating {
        func updateSearchResults(for searchController: UISearchController) {
            filterContentForSearchText(searchController.searchBar.text!)
        }
    }
    
    let vc = ViewController()
    let nav = UINavigationController()
    nav.viewControllers = [vc]
    
    PlaygroundPage.current.liveView = nav
    
    0 讨论(0)
提交回复
热议问题