自定义单元格和默认单元格同时显示在 tableview 上

Both custom cell and default cell is showing together on tableview

我正在用 customCell 制作一个简单的 tableview。和上面的 searchBar。但从 tableView 得到了一个奇怪的行为。 customCell 正在显示,但在其上方 defaultCell 也显示并且数据正在填充到 defaultCell 中,尽管我正在 customCell.

上设置数据

这是我得到的输出

https://i.imgur.com/xsTIsiz.png

如果仔细观察,您会看到我的自定义单元格 UI 显示在默认单元格下方。

我的自定义单元格:

https://i.imgur.com/J4UpRle.png

这是我来自 viewcontroller

的代码
import UIKit

class SuraSearchController: UIViewController {

    let searchController = UISearchController(searchResultsController: nil)
    let reciters = [Reciter(name: "Abdul Basit Abdus Samad", downloadUrl: ""),
                    Reciter(name: "Abdul Rahman Al-Sudais", downloadUrl: ""),
                    Reciter(name: "Ali Bin Abdur Rahman Al Huthaify", downloadUrl: ""),
                    Reciter(name: "Mishary Rashid Alafasy", downloadUrl: ""),
                    Reciter(name: "Cheik Mohamed Jibril", downloadUrl: ""),
                    Reciter(name: "Mohamed Siddiq El-Minshawi", downloadUrl: ""),
                    Reciter(name: "Mahmoud Khalil Al-Hussary", downloadUrl: ""),
                    Reciter(name: "Ibrahim Walk (English Only)", downloadUrl: ""),
                    Reciter(name: "Abu Bakr Al Shatri", downloadUrl: "")]

    var filteredReciters = [Reciter]()

    @IBOutlet weak var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()

//        definesPresentationContext = true
        initNavBar()
        initTableView()
        // Do any additional setup after loading the view.
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        self.navigationController?.setNavigationBarHidden(true, animated: animated)
    }

    func initNavBar() {
        // show navbar
        self.navigationController?.setNavigationBarHidden(false, animated: true)
        // set search bar delegates
        searchController.searchResultsUpdater = self
        searchController.obscuresBackgroundDuringPresentation = false
        // Customize Search Bar
        searchController.searchBar.placeholder = "Search Friends"
        let myString = "Cancel"
        let myAttribute = [ NSAttributedStringKey.foregroundColor: UIColor.white ]

        UIBarButtonItem.appearance(whenContainedInInstancesOf: [UISearchBar.self]).title = myString
        UIBarButtonItem.appearance(whenContainedInInstancesOf: [UISearchBar.self]).setTitleTextAttributes(myAttribute, for: .normal)

        if #available(iOS 11.0, *) {
            let scb = searchController.searchBar
            scb.tintColor = UIColor.white
            scb.barTintColor = UIColor.white

            if let textfield = scb.value(forKey: "searchField") as? UITextField {
                textfield.textColor = UIColor.blue
                if let backgroundview = textfield.subviews.first {

                    // Background color
                    backgroundview.backgroundColor = UIColor.white

                    // Rounded corner
                    backgroundview.layer.cornerRadius = 10
                    backgroundview.clipsToBounds = true
                }
            }
        }

        // Set search bar on navbar
        navigationItem.searchController = searchController
        navigationItem.hidesSearchBarWhenScrolling = false
    }

    func initTableView() {
        tableView.dataSource = self
        tableView.delegate = self
        tableView.register(UINib(nibName: "SuraSearchCell", bundle: nil), forCellReuseIdentifier: "SuraSearchCell")
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }    

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

    func filterContentForSearchText(_ searchText: String, scope: String = "All") {
        filteredReciters = reciters.filter({( reciter : Reciter) -> Bool in
            return reciter.name.lowercased().contains(searchText.lowercased())
        })

        tableView.reloadData()
    }

    func isFiltering() -> Bool {
        return searchController.isActive && !searchBarIsEmpty()
    }

    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destinationViewController.
        // Pass the selected object to the new view controller.
    }
    */

}

extension SuraSearchController: UITableViewDataSource, UITableViewDelegate {
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if isFiltering() {
            return filteredReciters.count
        }
        return reciters.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if let cell = tableView.dequeueReusableCell(withIdentifier: "SuraSearchCell", for: indexPath) as? SuraSearchCell {
            let candy: Reciter
            if isFiltering() {
                candy = filteredReciters[indexPath.row]
            } else {
                candy = reciters[indexPath.row]
            }
            cell.textLabel!.text = candy.name
            return cell
        }
        return UITableViewCell()
    }
}

extension SuraSearchController: UISearchResultsUpdating {
    // MARK: - UISearchResultsUpdating Delegate
    func updateSearchResults(for searchController: UISearchController) {
        filterContentForSearchText(searchController.searchBar.text!)
    }

}

以及表格视图单元格的代码

import UIKit

class SuraSearchCell: UITableViewCell {

    @IBOutlet weak var itemTitle: UILabel!

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
        // Configure the view for the selected state
    }

    func configureCell(item: Reciter) {
        itemTitle.text = item.name
    }

}

cell.textLabel 默认为 UITableViewCell 属性。您只需要为 customCell itemTitle 标签设置值。

cell.textLabel!.text = candy.name 替换为 cell. itemTitle!.text = candy.name,如下所示。

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if let cell = tableView.dequeueReusableCell(withIdentifier: "SuraSearchCell", for: indexPath) as? SuraSearchCell {
            let candy: Reciter
            if isFiltering() {
                candy = filteredReciters[indexPath.row]
            } else {
                candy = reciters[indexPath.row]
            }
            cell. itemTitle!.text = candy.name
            //OR
            cell.configureCell(candy) // IF your candy is of Reciter type
            return cell
        }
        return UITableViewCell()
    }

重用标识符名称可能有误。将名称与代码中使用的名称匹配。

cellForRowAtIndex 更新如下

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    if let cell = tableView.dequeueReusableCell(withIdentifier: "SuraSearchCell", for: indexPath) as? SuraSearchCell {
        let candy: Reciter
        if isFiltering() {
            candy = filteredReciters[indexPath.row]
        } else {
            candy = reciters[indexPath.row]
        }
        cell.configureCell(candy)
        return cell
    }
    return UITableViewCell()
}