Understanding how does Xcode handle reusable UITableViewCell

I have defined a class named c1 for a prototype cell like follows:




defined the code for c1 like this:


class c1 : UITableViewCell {
        
    public func configure(indexPath: IndexPath) -> Self {
        let place = places[indexPath.row]
        self.textLabel?.text = place.name
        self.detailTextLabel?.text = "\(place.timestamp)"
        return self
    }
}

* don't worry about undefined "places" so far


Inside the

UITableViewController
following code:


override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
       
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell1", for: indexPath)

        // Configure the cell...
        return cell.configure(indexPath: indexPath);
    }


But this doesn't work because obv. the compiler doesn't know about c1: "Value of type '

UITableViewCell
' has no member '
configure
'" at line 6.


I think: Because the dequeReusableCell() asks for a specified identifier "Cell1" which in turn has to be implemented by the custom class "c1" which is also specified in the storyboard. So the xcode editor has to accept the cells type according the custom class and shouldn't throw a compiler issue regarding the unknown ".configure" method.

Replies

You simply need to tell what type it is expected to be:


        guard let cell = tableView.dequeueReusableCell(withIdentifier: "Cell1", for: indexPath) as? C1 else { return UITableViewCell() }

Note that a class name should start with uppercase, hence C1 instead of c1 (c1 will be for instances of the class if you want).

In addition, it is better to give a meaningfull name, like PlaceCell


Your question is for IOS App ? Then you should move it to Cocoa Touch section.

But what can I do if more than one custom class comes into play? Is there any Swift capability to avoid long switch/case if/else branches of code to achieve that the cast could be become a kind of dynamic cast?


One more question: If the cell queried by the appr. identifier is not "on screen" but queued what will happen if it would be still asked for in the way guard let cell = <query unvisible cell>? It is nil?

If you have different types for cells, you have different content.


Hence, you need to address each independantly.


In that case, a simple way is to write :


if let cell = tableView.dequeueReusableCell(withIdentifier: "Cell1", for: indexPath) as? C1 {
     // Initialize cell as needed with C1 propertiesand return
     return cell
}

if let cell = tableView.dequeueReusableCell(withIdentifier: "Cell2", for: indexPath) as? C2 {
     // Initialize cell as needed with C2 properties and return
     return cell
}


That makes for a very easy to follow code.

How get I rid off the "Non-void function should return a value" when implementing the solution above?


I'm a newbie in Swift,iOS & Co. but for my opinion that leads to code duplication. I have googled as much as I could regarding this topic and I didn't catch it why on the one hand Swift is so complex and obv. "modern" but in the specific case it seems there's no smart solution available like switch or if/else, like suggested.


If each cell shows different content I want to use the broad capabilities of OOP. But because there's no way to make the cast part (as? <class name>) dynamic, I won't imagine the bunch of code by implement the dequeue() method for each class I would have.


Maybe some kind of Generics, Closures or any other concept that would help to get a smarter solution?

Which line exactly do you get the message ?


Did you write

return UITableViewCell()


as very last line of the tableView func ?


For your design question: How many types of cells did you get ?


Usually, we get a few (6 max)

Otherwise, you need probably to rethink how you designed the cells.

Are there only small variations ?

Then you could have the same cell, with all the UI Objects and hide those which are not used in some cases…


If you posted the whole code of the tableView, we could better help.


If each cell shows different content I want to use the broad capabilities of OOP. But because there's no way to make the cast part (as? <class name>) dynamic,

You can, declaring the class as objc, but that's a bit tricky and not sure it is really necessary here.

Look here: https://forums.developer.apple.com/thread/116041