Swift custom table cell - ios

I've been trying to use Custom Table cell in my swift app, and faced a problem: My application crashes when I run my app.
My custom table cell class is SimpleTableCell (Objective-C class)
and my cellForRowAtIndexPath method (swift) is:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCellWithIdentifier("SimpleTableItem", forIndexPath: indexPath)
let data = TableData[indexPath.row]
cell.textLabel?.text = data.description
if (data.image == nil)
{
cell.imageView?.image = UIImage(named:"image.jpg")
load_image(image_base_url + data.imageurl!, imageview: cell.imageView!, index: indexPath.row)
}
else
{
cell.imageView?.image = TableData[indexPath.row].image
}
return cell
}
My app crashes with the error:
unable to dequeue a cell with identifier SimpleTableItem - must register a nib or a class for the identifier or connect a prototype cell in a storyboard
What does it mean?

In the storyboard, select your tableView cell and in the attributes inspector, set the identifier to "SimpleTableItem". Hope this helps

dequeueReusableCellWithIdentifier is trying to find a cell with the identifier "SimpleTableItem", but it seems that you haven't given a cell that identifier anywhere. One way to do this is to choose a cell in the Table View in Storyboard, go to the Attributes Inspector and set its identifier to SimpleTableItem.

Related

Connect custom table view cell to separate view controller

So I'm trying to connect my custom table view cell into a table view in my main VC. The cell has its own xib file and its own swift file. I originally had the cell set up as a custom prototype cell in the table.
So the problem I have is in connecting my new custom cell to the viewcontroller. The code I have now is:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) ->
UITableViewCell {
let cell = table.dequeueReusableCell(withIdentifier: "cell")! as! CustomTableViewCell
return cell
}
Of course this set up is not working. The error I get during runtime is: "Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value" which I assume is referring to "cell" identifier. So my question is, can I connect my cell to this function, or do I need a new one to initiate and return "cell" to this table view?
You need to register the cell with the UITableView before you can use it. In your viewDidLoad method you need something like the following.
let nib = UINib(nibName: "CustomTableViewCell", bundle: nil)
tableView.register(nib, forCellReuseIdentifier: "cell")

dequeueReusableCellWithIdentifier doesn't return cell

I have a static table with one static section. Other sections are dynamic.
I create Table Section and Table Cell for dynamic section. Set identifier for Cell, set custom class for it and even do:
self.tableView.registerClass(UncheckedStoreTableViewCell.self, forCellReuseIdentifier: "StoreCell")
if i don't register it with code, then i get:
'unable to dequeue a cell with identifier StoreCell - must register a
nib or a class for the identifier or connect a prototype cell in a
storyboard'
So when i use this:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if indexPath.section == 0 {
return super.tableView(tableView, cellForRowAtIndexPath: indexPath)
}
let cell = tableView.dequeueReusableCellWithIdentifier("StoreCell", forIndexPath: indexPath) as! UncheckedStoreTableViewCell
return cell
}
It works. But if i'm trying to change label: cell.myLabel.text = "one"
or just print(cell.myLabel) got
BAD_INSTRUCTION
You can definitely use dynamic cells in a static table view.
Don't expect a static table view to register your cell's identifier for you. Just do it yourself.
Do you have outlets in the cell class to some view in interface builder? If I were you I wouldn't expect the table view to know about that. It will instantiate your cell class, and that's it. No outlets will be set. I think this is related: load nib in view subclass
By the way, if you've defined a custom .nib for your cell, there's this method: registerNib(_:forCellReuseIdentifier:)
You do not need to register your cell in code.
You have correctly set the identifier of the cell, however this is not enough. In addition to this you also need to open Identity Inspector for your cell and set the class of the cell to be UncheckedStoreTableViewCell. Here is an image showing you where you should set it:
Without this step Xcode will not be able to correctly associate your cell identifier with your custom cell as it doesn't know anything about it!

2 custom UITableViewCell in one UITableView Swift

I am trying to implement a custom table view which has different types of cells: type A and type B. All of my cells should be of type A, except for one that will be of type B. Whenever the users selects a cell, this one changes to type B.
My code is the following one:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let row = indexPath.row
if (row == typeBCellIndex) {
// Get Type B cell
let cell = tableView.dequeueReusableCellWithIdentifier(typeBCellIdentifier, forIndexPath: indexPath) as! TypeBTableViewCell
return cell
} else {
// Get Type A cell
let cell = tableView.dequeueReusableCellWithIdentifier(typeACellIdentifier, forIndexPath: indexPath) as! TypeATableViewCell
cell.detailLabel.text = "I am a type A cell"
return cell
}
}
The variable typeBCellIndex is initialised in 0, and this code gives an error when I add a new cell and try to dequeue the cell at index 1.
In Objective-C, as this links indicates, I would check if the cell is nil, and if not create a new instance of the corresponding cell. However, I am not sure if this concept applies to Swift, and in case it does, I don't know how to do it.
declare a variable cellindex before viewdidload method and initialize to 3 or any number
and in tableview design two different cells and assign unique identifier for each
code for tableview is
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell : UITableViewCell!
var row = indexPath.row
if(row == cellindex){
cell = tableView.dequeueReusableCellWithIdentifier("Cell2", forIndexPath: indexPath) as! UITableViewCell
}else{
cell = tableView.dequeueReusableCellWithIdentifier("Cell1", forIndexPath: indexPath) as! UITableViewCell
}
return cell
}
the cellindex row will be cell2 and other cells are cell1

Swift TableViewController reuseIdentifier never works

I'm working in Swift with one TableViewController with one prototype cell. The cell has a reuse identifier specified in the storyboard, but it never dequeues properly. I always get the "unexpectedly found nil while unwrapping an Optional value" error.
I've properly registered the class as follows:
self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "myNewCell")
The offending code is:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCellWithIdentifier("myNewCell") as UITableViewCell
let textField = cell.viewWithTag(123) as UITextField
textField.text = "test"
return cell
}
I feel like I've tried everything here but it never properly gives a cell with that identifier. Even using the fallback (if nil, create a cell with that identifier) still gives the error. It's definitely having trouble getting a cell with that identifier, but it's registered and specified in the storyboard... Any assistance is greatly appreciated!
When using cell prototypes, you do not call registerClass. The storyboard does that for you. If the cell prototype has its identifier specified, then just all dequeueReusableCellWithIdentifier and it should find your cell prototype without incident.
I'd suggest checking the spelling/capitalization of the identifier in storyboard and make sure it is identical to what is used in cellForRowAtIndexPath code.
I notice that you are trying to access a cell's label using a tag number. Nowadays, when dealing with custom cell layouts, we'd generally create our own table view subclass, e.g.:
// CustomTableViewCell.swift
import UIKit
class CustomTableViewCell: UITableViewCell {
#IBOutlet weak var customTextField: UITextField! // note, I would use something other than textLabel to avoid confusion with base class
}
We'd then go to our cell prototype and specify its base class:
We'd also set the cell prototype's identifier:
We'd then hook up the outlet between the cell prototype and our custom class #IBOutlet.
Having done all of that, the cellForRowAtIndexPath would be:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("myNewCell", forIndexPath: indexPath) as CustomTableViewCell
cell.customTextField.text = "Row \(indexPath.row)"
return cell
}
If dequeueReusableCellWithIdentifier is giving you problems then just don't use it.
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = UITableViewCell()
let textField = cell.viewWithTag(123) as UITextField
textField.text = "test"
return cell
}

Multiple table views in a single storyboard swift

Im trying to have 2 tableview in a single view controller with one tableview being static while
the other dynamic.
My view controller is set up like so
The top half being the static tableview.
i created ibOutlets for both tableViews but i can't seem to be able to customise the tables.
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell2", forIndexPath: indexPath) as UITableViewCell
//tableview2 is the dynamic tableView.
if (tableView == self.tableView2){
print("Tableview2")
}
else{
println("HELLLO")
}
return cell
}
i get the error * Assertion failure in -[UITableView dequeueReusableCellWithIdentifier:forIndexPath:], /SourceCache/UIKit_Sim/UIKit-3318.16.14/UITableView.m:6116
2014-10-23 22:31:52.246 Recipe app[2857:504809] * Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'unable to dequeue a cell with identifier cell2 - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'.
As error says you "must register a nib or a class for the identifier or connect a prototype cell in a storyboard".
Do this on viewDidLoad or awakeFromNib.
self.tableView.registerClass(UITableViewCell.classForCoder(), forCellReuseIdentifier:"cell2")
Or you have to make prototype cells in storyboard and give it "cell2" identifier
Assuming you have given the prototype cells for your dynamic table the reuseIdentifier "cell2", move this line:
let cell = tableView.dequeueReusableCellWithIdentifier("cell2", forIndexPath: indexPath) as UITableViewCell
into either the if ... clause, or the else ... clause (whichever deals with the dynamic table). If tableView is the static table, it throws the error.

Resources