【问题标题】:iOS Swift - Filtering contents of UITableView that has custom cell with Search Bar and Search DisplayiOS Swift - 过滤具有搜索栏和搜索显示的自定义单元格的 UITableView 的内容
【发布时间】:2014-11-28 20:17:04
【问题描述】:

我在 iPhone 的 Swift 项目中遇到了搜索栏和搜索显示的问题。我在视图中添加了一个带有自定义单元格的 UITableView。 Cell 的 Indetifier 设置为“QuestionCell”,Class 设置为“QuestionCellTableViewCell”。我在该单元格中添加了两个标签,并将标签的出口添加到单元格类中。 我的目标是过滤 UITableView 的内容。

这是我的视图控制器: DomandeViewController.swift

import UIKit

class DomandeViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UISearchDisplayDelegate, UISearchBarDelegate {

    var arrayDomande = [Domanda]()
    var areaDomande: Area = Area()
    var argomentoDomande: Argomento = Argomento()
    var domandeFiltrate = [Domanda]()

    @IBOutlet weak var questionTableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        arrayDomande = ModelManager.instance.getQuestionsWithArguments(inAreaId: areaDomande.id, aboutId: argomentoDomande.id)
        self.searchDisplayController!.searchResultsTableView.registerClass(QuestionCellTableViewCell.classForCoder(), forCellReuseIdentifier: "QuestionCell")
    }

    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        if(tableView == self.searchDisplayController!.searchResultsTableView){
            return 1
        }else{
            return 1
        }
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if tableView == self.searchDisplayController!.searchResultsTableView {
            return domandeFiltrate.count
        } else {
            return arrayDomande.count
        }
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        var cell = tableView.dequeueReusableCellWithIdentifier("QuestionCell") as QuestionCellTableViewCell

        var domanda = Domanda()

        if tableView == searchDisplayController!.searchResultsTableView {
            domanda = domandeFiltrate[indexPath.row]
        } else {
            domanda = arrayDomande[indexPath.row]
        }

        cell.testoLabel.text = domanda.testo
        cell.numeroLabel.text = String(domanda.numero)

        return cell
    }

    func filterContentForSearchText(searchText: String) {
        // Filter the array using the filter method
        filteredDomande = arrayDomande.filter({( domanda: Domanda) -> Bool in
            let stringMatch = domanda.testo.rangeOfString(searchText)
            return stringMatch != nil
        })
    }

    func searchDisplayController(controller: UISearchDisplayController, shouldReloadTableForSearchString searchString: String!) -> Bool {
        self.filterContentForSearchText(searchString)
        return true
    }
}

这是我的 QuestionCellTableViewCell.swift

import UIKit

class QuestionCellTableViewCell: UITableViewCell {

    @IBOutlet weak var testoLabel: UILabel!
    @IBOutlet weak var numeroLabel: 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
    }

}

这是我的 Domanda.swift

import UIKit

class Domanda: NSObject {
    var numero: Int = Int()
    var testo: String = String()
    var preferita: Bool = Bool()
    var visualizzato: Int = Int()
    var area: Int = Int()
    var argomento: Int = Int()
}

一切正常,直到我在搜索栏中搜索一个字符串:应用程序崩溃并且控制台返回:

“致命错误:在展开 Optional 时意外发现 nil 价值”

通过调试,我看到“cell”存在,但它的出口(testoLabel 和 numeroLabel)为零,因此应用程序崩溃

cell.testoLabel.text = domanda.testo

如果我在 viewDidLoad() 中删除

self.searchDisplayController!.searchResultsTableView.registerClass(QuestionCellTableViewCell.classForCoder(), forCellReuseIdentifier: "QuestionCell")

当在搜索栏中输入一些文本时应用程序崩溃,执行时出现相同的错误

var cell = tableView.dequeueReusableCellWithIdentifier("QuestionCell") as QuestionCellTableViewCell

如果我添加 viewDidLoad()

self.questionTableView.registerClass(QuestionCellTableViewCell.classForCoder(), forCellReuseIdentifier: "QuestionCell")

应用程序在 cell.testoLabel.text 处不断崩溃,但这次是在启动时。

对我有什么建议? 非常感谢,感谢您的帮助!

安德烈亚

编辑:

今天我做了其他测试,结果如下:如果我将 searchResultsTableView 的单元格用作基本单元格,一切正常,但如果我尝试使用自定义单元格的插座,应用程序会崩溃。这是工作代码:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        var cell = tableView.dequeueReusableCellWithIdentifier("QuestionCell") as QuestionCellTableViewCell
        var domanda = Domanda()

        if tableView == self.searchDisplayController!.searchResultsTableView {
            domanda = filteredDomande[indexPath.row]

            cell.textLabel.text = domanda.testo
        } else {
            domanda = arrayDomande[indexPath.row]

            cell.testoLabel.text = domanda.testo
            cell.numeroLabel.text = String(domanda.numero)
        }

        return cell
    }

最后,我似乎无法将我的自定义单元格与 searchResultsTableView 一起使用。我的错误在哪里?再次感谢您!

【问题讨论】:

    标签: uitableview swift ios8 uisearchbar custom-cell


    【解决方案1】:

    终于找到了解决办法。我在我的项目中添加了一个新的用户界面空文件,然后我在这个新的 nib 文件中创建了一个单元格,并为它分配了我的自定义单元格类。在 Interface Builder 中,我将 questionTableView 的 Prototype Cells 设置为 0,然后我在 viewDidLoad() 中为 questionTableView 和 searchResultsTableView 注册了 Nib forCellReuseIdentifier。这是我的代码:

    var cellIdentifier = "questionCell"
    
    @IBOutlet weak var questionTableView: UITableView!
    
    override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view, typically from a nib.
            arrayDomande = ModelManager.instance.getQuestionsWithArguments(inAreaId: areaDomande.id, aboutId: argomentoDomande.id)
    
            var nib = UINib(nibName: "QuestionCellTableViewCell", bundle: nil)
            self.searchDisplayController!.searchResultsTableView.registerNib(nib, forCellReuseIdentifier: cellIdentifier)
            self.questionTableView.registerNib(nib, forCellReuseIdentifier: cellIdentifier)
    }
    
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
            var cell: QuestionCellTableViewCell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as QuestionCellTableViewCell
            var domanda = Domanda()
    
            if tableView == self.searchDisplayController!.searchResultsTableView {
                domanda = filteredDomande[indexPath.row]
            } else {
                domanda = arrayDomande[indexPath.row]
            }
            cell.testoLabel.text = domanda.testo
            cell.numeroLabel.text = String(domanda.numero)
    
            return cell
        }
    

    【讨论】:

    • 您不应再在 IOS 8 中使用 searchDisplayController,因为它已被标记为已弃用,并将在未来的版本中删除。改用 UiSearchController。
    • 感谢克里斯蒂安的建议!我在 Interface Builder 中使用了 Search Bar 和 Search Display Controller 组件,默认情况下它使用 UISearchDisplayController 作为类。希望苹果能改变它在IB中的默认类!
    • 您需要手动移除 DisplayController atm。这有点垃圾。需要明确的是,您的应用不会因为使用不推荐使用的类而被拒绝,但我猜它会在 iOS 9 中被删除
    • 确实,该应用程序被批准没有问题;)感谢您的提示,我开始努力删除已弃用的类!再次感谢克里斯蒂安!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-06
    • 1970-01-01
    • 2016-01-04
    • 1970-01-01
    • 2015-11-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多