iOS Swift - Filtering contents of UITableView that has custom cell with Search Bar and Search Display
custom-cell, ios8, swift, uisearchbar, uitableview
Solution
Finally I found a solution. I added a new user interface empty file to my project, then I created a cell in this new nib file and I assigned to it my custom cell class. In Interface Builder I set Prototype Cells to 0 for questionTableView and then I registered Nib forCellReuseIdentifier in viewDidLoad() both for questionTableView that for searchResultsTableView. This is my code:
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
}
Problem
I have an issue with Search Bar and Search Display in a Swift project for iPhone. I added one UITableView with custom cells to a View. Cell have Indetifier set to "QuestionCell" and Class set to "QuestionCellTableViewCell". I added to that cell two label and I added outlets for the labels to cell class. My goal is to filter the contents of the UITableView. This is my ViewController: 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 } } ``` This is my 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 } } ``` And this is my 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() } ``` Everything works fine, until I search a string in Search Bar: the application crashes and the console returns: "fatal error: unexpectedly found nil while unwrapping an Optional value" With debug I see that "cell" exists, but its outlets (testoLabel and numeroLabel) are nil and so the app crashes on ``` cell.testoLabel.text = domanda.testo ``` If I remove in viewDidLoad() ``` self.searchDisplayController!.searchResultsTableView.registerClass(QuestionCellTableViewCell.classForCoder(), forCellReuseIdentifier: "QuestionCell") ``` the app crashes when is entered some text in Search Bar with same error when executes ``` var cell = tableView.dequeueReusableCellWithIdentifier("QuestionCell") as QuestionCellTableViewCell ``` If I add in viewDidLoad() ``` self.questionTableView.registerClass(QuestionCellTableViewCell.classForCoder(), forCellReuseIdentifier: "QuestionCell") ``` the app keep crashing at cell.testoLabel.text but this time at startup. Some advice for me? Thank you very much, I appreciate any help! Andrea EDIT: Today I did other tests and here's the result: if I use the cells of searchResultsTableView as Basic cells everything works fine, but if I try to use the outlets of my custom cell the application crashes. This is the working code: ``` 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 } ``` In the end I can't seem to use my custom cell with searchResultsTableView. Where is my error? Thank you so much again!