Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom UITableViewCell register class in Swift

In my application, I fill the table on the basis of the array. The table uses custom UITableViewCell. Everything works fine, table is filled. Then I add Search Display Controller to my UITableViewController, no write code to handle the search, simply add the controller. When you run the application, the table is still filled.But if I try to click on the search bar, I get the error:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'unable to dequeue a cell with identifier CitiesListCell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'

I try to add to my viewDidLoad function in UITableViewController line:

self.tableView.registerClass(MyCell.classForCoder(), forCellReuseIdentifier: kCellIdentifier)

Launch the application and immediately get the error:

fatal error: unexpectedly found nil while unwrapping an Optional value

In line cell.cellMyCity.text = cellText

What am I doing wrong?

This is my Custom UITableViewCell class:

import UIKit

class MyCell: UITableViewCell {

@IBOutlet var cellMyImage: UIImageView
@IBOutlet var cellMyCity: UILabel
@IBOutlet var cellMyCountry: UILabel
@IBOutlet var cellMyTemp: UILabel

init(style: UITableViewCellStyle, reuseIdentifier: String!) {
    super.init(style: style, reuseIdentifier: reuseIdentifier)
}

override func awakeFromNib() {
    super.awakeFromNib()
}

override func setSelected(selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)

}
}

This is code for cell:

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

    var cell = tableView.dequeueReusableCellWithIdentifier(kCellIdentifier, forIndexPath: indexPath) as MyCell!

    if cell == nil {
        cell = MyCell(style: UITableViewCellStyle.Default, reuseIdentifier: kCellIdentifier)
    }

    let cellText: String? = dataWeatherSelectedCity[indexPath.row].name as  String
    println("Строка: \(cellText)")
    cell.cellMyCity.text = cellText

    let cellSubtitle: String? = dataWeatherSelectedCity[indexPath.row].country as String
    cell.cellMyCountry.text = cellSubtitle

    cell.cellMyImage.image = UIImage(named: "Blank52")

    var currentCityWeatherURL = "http://api.wunderground.com/api/\(self.myAPI.kWundergroundApiKey)/conditions/lang:RU/q/zmw:\(self.dataWeatherSelectedCity[indexPath.row].zmv).json"

    var fullObservation:NSDictionary = self.myAPI.jsonParsingWeather(currentCityWeatherURL)
    var currentObservation:NSDictionary = fullObservation.valueForKey("current_observation") as NSDictionary

    var currentWeather = self.myAPI.parsingOneCityCurrentCondition(currentObservation)       
    cell.cellMyImage.image = currentWeather.image
    cell.cellMyTemp.text = currentWeather.temp
    return cell
}

Property in TableViewCell: enter image description hereenter image description hereenter image description here

Table without self.tableView.registerClass(MyCell.classForCoder(), forCellReuseIdentifier: kCellIdentifier) or self.tableView.registerClass(MyCell.self, forCellReuseIdentifier: kCellIdentifier):

enter image description here

like image 764
Alexey Nakhimov Avatar asked Jul 15 '14 06:07

Alexey Nakhimov


People also ask

How do I register a custom cell in Swift?

Registering the cell We need a way to tell the UITableView to use our new cell instead of the default cell. To do that we register the XIB file in the view controller that has the UITableView . Then, open HabitsTableViewController. swift to finish registering the cell.

How do I register tableView?

There are two variants to register , but both take a parameter called forCellReuseIdentifier , which is a string that lets you register different kinds of table view cells. For example, you might have a reuse identifier "DefaultCell", another one called "Heading cell", another one "CellWithTextField", and so on.

How can we use a reusable cell in UITableView?

For performance reasons, a table view's data source should generally reuse UITableViewCell objects when it assigns cells to rows in its tableView(_:cellForRowAt:) method. A table view maintains a queue or list of UITableViewCell objects that the data source has marked for reuse.


1 Answers

what I did for making that working is something like this:

class MainViewController: UIViewController {

    // ...

    @IBOutlet var tableView: UITableView

    override func viewDidLoad() {
        super.viewDidLoad()

        self.tableView.registerNib(UINib(nibName: "UICustomTableViewCell", bundle: nil), forCellReuseIdentifier: "UICustomTableViewCell")

        // ...
    }

    // ...

}

NOTE: If I use the –registerClass(_: forCellReuseIdentifier:) method, the xib file won't be loaded, therefore the actual custom interface will not appear unless you add the content programatically to the cell. if you'd like to load the interface from a nib file, you need to register the cell with its nib.


conforming the essential protocols:

extension MainViewController: UITableViewDataSource {
    
    func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
        return 3
    }
    
    func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
        let cell: UICustomTableViewCell = tableView.dequeueReusableCellWithIdentifier(UICustomTableViewCell.reuseIdentifier) as UICustomTableViewCell
        println(cell)
        return cell;
    }
    
}

//

extension MainViewController: UITableViewDelegate {
    
    func tableView(tableView: UITableView!, heightForRowAtIndexPath indexPath: NSIndexPath!) -> CGFloat {
        return 44.0
    }
    
}

and the custom cell class was a very generic one with a meaningful name as UICustomTableViewCell:

class UICustomTableViewCell: UITableViewCell {

    class var reuseIdentifier: String {
        get {
            return "UICustomTableViewCell"
        }
    }
    
    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
    }
    
}

with a quite random interface:

random custom interface

and these settings of custom class and reuse identifier:

custom classreuse identifier


and the final result on my screen is as I expected with 3 rows:

the final result in practice

NOTE: for further customisation of the custom cells you may need extend the code above.

UPDATE

with UISearchBar, the final result would be like this:

with Search Bar

like image 103
holex Avatar answered Oct 03 '22 02:10

holex