1

In Swift with dequeueReusableCell API we don't have control over creating of a new instance of TableViewCell. But what if I need to pass some initial parameters to my custom cell? Setting parameters after dequeue will require a check if they have been already set and seem to be uglier than it was in Objective-C, where it was possible to create custom initializer for a cell.

Here is a code example of what I mean.

Objective-C, assuming that I don't register a class for the specified identifier:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString* reuseIdentifier = @"MyReuseIdentifier";
    UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
    if (!cell)
    {
        cell = [[MyTableViewCell alloc] initWithCustomParameters:...]; // pass my parameters here

    }
    return cell;
}

Swift:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "MyReuseIdentifier")
    if let cell = cell as? MyTableViewCell {
       // set my initial parameters here
       if (cell.customProperty == nil) {
           cell.customProperty = customValue
       }
    }
}

Do I miss something or it's how it supposed to work in Swift?

Anastasia
  • 3,024
  • 1
  • 23
  • 34
  • Objective-C and Swift behave exactly the same. You are using different APIs and you don't have control in ObjC either. – vadian Apr 30 '20 at 15:55
  • @vadian You are right, I was using different deque- methods, fixed that for consistency. Actually I do have control in Objective-C: if I don't register cell for reuse identifier, the code I wrote in example works. Moreover, I tried to do the same in Swift (not registering) and I have the same behaviour as in Objective-C now. This seems to answer my question. – Anastasia Apr 30 '20 at 20:29

3 Answers3

0

In swift or objective-c dequeueReusableCell will return a cell if there is an available 1 or will create another if there isn't , btw what you do in objc can be done in swift it's the same

Shehata Gamal
  • 98,760
  • 8
  • 65
  • 87
  • In Objective-C, if I don't register a class for the specified identifier, the cell won't be created automatically when calling dequeueReusableCell. And I actually don't. (need to add this info to the question) – Anastasia Apr 30 '20 at 15:35
  • and why even you try to dequeue a cell that is not registered ? btw objc will neglect nulls – Shehata Gamal Apr 30 '20 at 18:15
  • Well it workes like I wrote in my example. May be because register was added later to the API than dequeue. Docs on dequeue says " If no cell is available for reuse and you did not register a class or nib file, this method returns nil." And I find this behaviour very convinient as you know if you have a new cell or reused one. – Anastasia Apr 30 '20 at 19:11
  • Interesting: I tried to not register a cell in Swift, now it works as I wanted it to: returns either nil or dequeued cell – Anastasia Apr 30 '20 at 20:36
0

Always before UITVCells will reuse inside your Cell class will prepareForReuse() called. You can use this method to reset all content like imageView.image = nil.

Use the initial from UITVCell init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) to know if the cell was created.

If you want to know this infomations inside your tableView class, use func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) delegate method.

PS: Dont forget to call super.

A. Amini
  • 521
  • 8
  • 15
0

The working approach is basically the same as Objective-C: Do NOT register cell for "MyReuseIdentifier" and use dequeueReusableCell(withIdentifier: )

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    var cell = tableView.dequeueReusableCell(withIdentifier: "MyReuseIdentifier")
    if cell == nil {
        cell = MyTableViewCell.initWithCustomParameters(...)
    }
    return cell
}
Anastasia
  • 3,024
  • 1
  • 23
  • 34