Search code examples
iosswiftuitableviewcustom-celluisearchcontroller

Custom cell with UISearchController in UITableViewController (result controller)


I am trying to implement a UISearchController (not UISearchDisplayController which is deprecated)

I face a ridiculously time eating issue.

When I try to dequeueResusableCellWithIdentifier it doesn't works with my CellAutocompletion (UITableViewCell subclassing)

Like this :

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

    let item = filteredProducts[indexPath.row]

    let cell:CellAutocompletion = self.tableView.dequeueReusableCellWithIdentifier("suggestionCell") as! CellAutocompletion

    cell.itemLabel?.text = item.item_name;

    return cell
}

This throw me fatal error: unexpectedly found nil while unwrapping an Optional value

BUT when I do this :

    let cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "suggestionCell");

It works. So with a Default iOS cell, it works, with my custom cell not. Any idea?

I think I ask the wrong tableview but considering I am inside a TableviewController included inside UISearchController which is used by another VC, I am lost.

My main VC which instanciate my searchController and the TableViewController where I have issue.

    //ViewDidLoad
    resultsTableController = ProductResultTabController();
    resultsTableController.tableView.delegate = self;

    self.searchController = UISearchController(searchResultsController: resultsTableController);
    searchController.searchResultsUpdater = self;
    searchController.dimsBackgroundDuringPresentation = true;

    searchController.searchBar.sizeToFit()
    tableView.tableHeaderView = searchController.searchBar

My CustomCell Class

class CellAutocompletion:UITableViewCell{

@IBOutlet weak var itemLabel: UILabel!
@IBOutlet weak var parentItemLabel: UILabel!

}

ProductResultTabController (subclass of TableViewController)

class ProductResultTabController: UITableViewController {
var filteredProducts = [ITEM]();

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1;
}

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

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let item = filteredProducts[indexPath.row]

    let cell:CellAutocompletion = self.tableView.dequeueReusableCellWithIdentifier("suggestionCell") as! CellAutocompletion!

    cell.itemLabel?.text = item.item_name;

    return cell
}


}

Solution

  • As I understand, your ProductResultTabController lives in the storyboard with the cell prototype. As a consequence, call resultsTableController = ProductResultTabController() doesn't do the most essential part of creating a TableViewController, which is registering your tableView: for a class or nib. You could create your cell in a nib and call tableview.registerNib: in your PRTC viewDidLoad:, but there is an other, slightly more convenient way:

    1. Create your PRTC in the storyboard and prototype the cell (I believe you've already done that)
    2. In SB, go to attributes inspector and give the controller a storyboard ID

    Giving a storyboard ID in Attributes Inspector

    3 - In your main VC's viewDidLoad:, replace resultsTableController = ProductResultTabController()`by the following:

    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    resultsTableController = storyboard.instantiateViewControllerWithIdentifier(myStoryboardID)