ios - 将搜索栏添加到自定义表格 View

标签 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()
        }
    }

}

最佳答案

从 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()
        }
    }
}

关于ios - 将搜索栏添加到自定义表格 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44239478/

相关文章:

ios - 无法将数据设置为 prepareForSegue 中的数组

ios - 获取在 VNDetectTextRectanglesRequest 完成处理程序上的 VNImageRequestHandler 中使用的 cvPixelBuffer

ios - 获取 UIColor 的深色样式

ios - 需要将 firebase 远程配置中的值更新到我的 plist

iOS 颜色过渡导航栏

ios - Swift 必须调用父类(super class) uiinputviewcontroller 的指定初始化器

ios - 应用程序卸载/重新安装后 CoreData + Cloudkit fetch() 不返回任何结果

ios - 是否可以在 UITableViewCell 的单个按钮上快速设置文本

ios - MutableCollectionType 的 Swift 扩展不适用于泛型类型数组

ios - UITabbar 图像上下移动