Swift tableView.dequeueReusableCell Never Returning Nil
You don't need to check if the cell is nil using this dequeue method, as long as you've register a cell class for reuse, or provided a prototype in Interface Builder.
let cell = tableView.dequeueReusableCellWithIdentifier("CellSubtitle", forIndexPath: indexPath) as! UITableViewCell
If however, you want to continue manually initializing the cells, you can use the following dequeue method instead. (keep in mind, this is the old way)
let cell = tableView.dequeueReusableCellWithIdentifier("CellSubtitle") as? UITableViewCell
Then as far as initializing the detailTextLabel goes, you don't have to. It's built into the cell, and by specifying that the cell's style should be subtitle, that label will be set up for you.
Note that the casts aren't necessary in Swift 2.
Jacob
Software Engineer at MediaBrains, Inc. Carnegie Mellon University Information Systems, C/O 2020
Updated on June 09, 2022Comments
-
Jacob almost 2 years
This is my Swift code to generate my table view. I am trying to set up a tableView with detail labels. The problem is that the following code is never called.
if (cell == nil) { println("1") cell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "CellSubtitle") //cell = tableViewCell }
Here is the code you need for the method:
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! { println("start TableViewCellForRowAtIndexPath") var cell: UITableViewCell! = tableView.dequeueReusableCellWithIdentifier("CellSubtitle", forIndexPath: indexPath) as UITableViewCell if (cell == nil) { println("1") cell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "CellSubtitle") //cell = tableViewCell } cell.textLabel.text = instructions[indexPath.row].text println("2") //cell.detailTextLabel cell.detailTextLabel.text = "HI" println("3")
Here is the console output for the method:
start load 1 2 done load start TableViewCellForRowAtIndexPath 2 fatal error: Can't unwrap Optional.None (lldb)
How can I initialize the
detailTextLabel
in order to insert text? When I try to set the text for the label, I receivefatal error: Can't unwrap Optional.None.
Why am I receiving this error?
-
Jacob almost 10 yearsPlease see the updated question. Even after changing the method like you stated, when I set text to to
detailTableView
I still receive the errorfatal error: Can't unwrap Optional.None
-
Mick MacCallum almost 10 years@jbman223 What kind of objects are you storing in your instructions array?
-
Jacob almost 10 yearsthe instructions are a custom object to hold data for the text, detail text, and image, and other information.
-
rdelmar almost 10 yearsThe second way you show, using the older dequeue method will also not ever return a nil cell if the cell is made in the storyboard (assuming that the identifier is correct).
-
Roi Mulia almost 9 yearslol funny you updated the question a hour ago. If i want to initialize the cell only once for certain properties, like border width, how can i check using your method if he already initialized , and not do the same thing every time?
-
Mick MacCallum almost 9 years@roimulia Typically what you would do in this situation is use with first of these two methods, and move your setup code into the initializer (or layoutSubviews/etc what ever is appropriate) in a UITableViewCell subclass. That way, the code will only be executed once (in the case of init) for each cell that the table determines it needs. It has to make enough of them to exhaust your data source, or fill the table's bounds (which ever comes first).
-
Roi Mulia almost 9 yearsSo generally move this to the cell subclass? :)
-
Mick MacCallum almost 9 years@roimulia When possible yes. It will help keep the code organized. Of course you'll need to keep logic for things like pulling data out of your datasource in cellForRowAtIndexPath/willDisplayCell/etc.
-
Roi Mulia almost 9 yearsThanks! Is it the same behavior if for instance i want to put an image view inside cell? because when i tried doing this only from cellforrowatindexpath it started duplicated(because if the reuse) lol
-
Mick MacCallum almost 9 years@roimulia Well it depends. If you have a single image that will be displayed in all the cells, it's better to move that work into the cell's initializer. However, if the image will be different depending on the indexPath, you'll want to keep the logic in cellForRowAtIndexPath, but in that case you need to make sure to reset properties where appropriate. For example, if some cells should have images, but others shouldn't you need to explicitly set
imageView.image
to nil in the cases where no image should be shown, because of the cell reuse. -
Roi Mulia almost 9 yearsStarting to get it :) so in the case of different images depends on the cell index, this imageView will be the "outlet" from the cell subclass or i will only declare it only in the cellForRowAtIndexPath?
-
Roi Mulia almost 9 yearsI tied doing that, didnt work so well. Im trying to put an image only 3 cells out of 10(for example), should i create a ImnageView from cellforindexpath or create it in the subclass?
-
scord almost 9 yearscell is never nil here.