将搜索栏添加到自定义表视图

时间:2017-05-29 09:52:00

标签: ios swift

我正在使用searchBar创建自定义tableViewController。我创建了一个自定义单元类" DataCell"。

使用以下代码时,不会显示searchBar,也不会显示标签数组。

我该如何解决这个问题?

 import UIKit

class DataCell: UITableViewCell{

    @IBOutlet weak var label: UILabel!

}

class SearchController: UIViewController, UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate {

    @IBOutlet weak var tableView: UITableView!
    @IBOutlet weak var searchBar: UISearchBar!

    var isSearching = false


    var data = ["a","b","c","d","e"]
    var filterData = [String]()

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.delegate = self
        tableView.dataSource = self

        searchBar.delegate = self
        searchBar.returnKeyType = UIReturnKeyType.done

    }

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

            if isSearching{
                return filterData.count
            }

        return data.count
    }



    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        if let cell = tableView.dequeueReusableCell(withIdentifier: "DataCell", for: indexPath) as? DataCell {

            let text: String!

            if isSearching {

                text = filterData[indexPath.row]
            } else {
                text = data[indexPath.row]
            }

            return cell

        } else {
            return UITableViewCell()
        }
    }

    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        if searchBar.text == nil || searchBar.text == ""{
            isSearching = false

            view.endEditing(true)

            tableView.reloadData()
        }else {
            isSearching = true

            filterData = data.filter({$0 == searchBar.text})

            tableView.reloadData()
        }
    }

}

1 个答案:

答案 0 :(得分:2)

从iOS 8开始,您应该使用[UISearchController][1],您需要为其创建2个类。一个SearchController和一个ResultsController。我们首先创建一个通用的UITableView类:

import UIKit

class DataCell: UITableViewCell {
    @IBOutlet weak var label: UILabel!

    func configureCell(_ text: String) {
        label.text = text
    }
}

然后,对于搜索类:

class SearchController: UIViewController {

    @IBOutlet weak var tableView: UITableView!
    var searchController: UISearchController!
    var resultController: ResultController?

    var data = ["a","b","c","d","e"]

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.register(TableCell.self, forCellReuseIdentifier: "DataCell")
        tableView.register(UINib(nibName: "DataCell", bundle: Bundle.main), forCellReuseIdentifier: "DataCell")

        // Search Results 
        resultController = ResultController() 
        setupSearchControllerWith(resultController!) 
        if #available(iOS 9.0, *) { 
            searchController?.loadViewIfNeeded() 
        } 

        tableView.delegate = self
        tableView.dataSource = self
        resultController.tableView.delegate = self
    }
}

extension: SearchController: UITableViewDataSource  {

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return data.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        if let cell = tableView.dequeueReusableCell(withIdentifier: "DataCell", for: indexPath) as? DataCell {
            return cell.configureCell(data[indexPath.row])
        } else {
            return UITableViewCell()
        }
    }
}

extension SearchController: UITableViewDelegate {

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 
        if tableView == resultController?.tableView { 
            performSegue(withIdentifier: "DetailView", sender: resultController?.filterData[indexPath.row]) 
        } else { 
            performSegue(withIdentifier: "DetailView", sender: data[indexPath.row]) 
        } 
    }
}

extension SearchController: UISearchResultsUpdating, 
  UISearchControllerDelegate, 
  UISearchBarDelegate   { 

    func updateSearchResults(for searchController: UISearchController) {
        let resultsTable = searchController.searchResultsController as! ResultVC
//        resultsTable.query = searchController.searchBar.text!
        resultsTable.filterData = data.filter({
            $0 == searchController.searchBar.text!
        })
        resultsTable.tableView.reloadData()
    }

    func setupSearchControllerWith(_ results: ResultVC) { 
        // Register Cells 
        results.tableView.register(TableCell.self, forCellReuseIdentifier: "DataCell") 
        results.tableView.register(UINib(nibName: "DataCell", bundle: Bundle.main), forCellReuseIdentifier: "DataCell") 

        // We want to be the delegate for our filtered table so didSelectRowAtIndexPath(_:) is called for both tables. 
        results.tableView.delegate = self 
        searchController = UISearchController(searchResultsController: results)       

        // Set Search Bar 
        searchController.searchResultsUpdater = self 
        searchController.searchBar.sizeToFit() 
        tableView.tableHeaderView = searchController.searchBar 

        // Set delegates 
        searchController.delegate = self 
        searchController.searchBar.delegate = self
    }  

    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        if searchBar.text == nil || searchBar.text == ""{
            isSearching = false
            view.endEditing(true)
            tableView.reloadData()
        } else {
            isSearching = true
            filterData = data.filter({$0 == searchBar.text})
            tableView.reloadData()
        }
    }
}

然后,对于ResultsController类:

class ResultController: UIViewController {

    @IBOutlet weak var tableView: UITableView!
    var filterData = [String]()

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.register(TableCell.self, forCellReuseIdentifier: "DataCell")
        tableView.register(UINib(nibName: "DataCell", bundle: Bundle.main), forCellReuseIdentifier: "DataCell")

        tableView.dataSource = self   
    }
}

extension ResultController: UITableViewDataSource {

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        let rowCount = filterData.count
        // When no data insert centered label 
        if rowCount == 0 { 
            blankView(with: textForEmptyLabel) 
        } else { 
            // Remove empty table label 
            tableView.backgroundView = nil 
            tableView.separatorStyle = .singleLine 
        } 
        return rowCount
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        if let cell = tableView.dequeueReusableCell(withIdentifier: "DataCell", for: indexPath) as? DataCell {
            return cell.configureCell(filterData[indexPath.row])
        } else {
            return UITableViewCell()
        }
    }
}