iOS Uitableview: What's the Different Between "Cellforrowatindexpath" and "Willdisplaycell: Forrowatindexpath:"

iOS UITableView: what's the different between cellForRowAtIndexPath and willDisplayCell: forRowAtIndexPath:

You are right, cell configuration can (in theory) be done in both methods.

However, almost all UITableView have a data source which implements cellForRowAtIndexPath: (it is a required method in the protocol). On the other hand, the willDisplayCell:forRowAtIndexPath: (which is a method of the delegate, not the data source) is optional.

As configuring a cell is usually dependent on the data you want to show, cellForRowAtIndexPath: is by far the most common place to do cell configuration. (I can't even remember using willDisplayCell:forRowAtIndexPath:).

There's one notable exception: when you are using a storyboard and static cells (instead of cell prototypes), you can't do anything useful in cellForRowAtIndexPath: (because dequeueReusableCellWithIdentifier: returns nil), so you have to do configuration in willDisplayCell:forRowAtIndexPath:, viewWillAppear: or other methods.

@NSDeveloper: you're right. Thanks for the hint.

UITableView: willDisplayCell: forRowAtIndexPath: method - what does this method do?

Do you mean willDisplayCell: instead of willDisplayingCell:?

https://developer.apple.com/library/ios/documentation/uikit/reference/UITableViewDelegate_Protocol/Reference/
Reference.html#//apple_ref/occ/intfm/UITableViewDelegate/tableView:willDisplayCell:forRowAtIndexPath:

UITableView cellForRowAt vs willDisplay

Always set up your cell inside func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell

Apple documentation says about cellForRowAt:

Asks the data source for a cell to insert in a particular location of the table view.

tableView(_:cellForRowAt:)

willDisplay on the other can be used to override certain properties of a cell just before it is drawn to view. I would suggest if you are not sure about willDisplay just do all your set up in cellForRowAt.

Apple's doc says about willDisplay:

This method gives the delegate a chance to override state-based properties set earlier by the table view, such as selection and background color.

More on willDisplay is here in Apple's documentation:
tableView:willDisplayCell:forRowAtIndexPath:

EDIT: After reading the link you provided - I reaffirm that unless you really have a specific reason to setup your cell in willDisplayCell, just do it in cellForRowAt.

Should I set the cell on cellForItemAtIndexPath or willDisplayCell?

Yes its true that both perform the same function but use cellForRowAtIndexPath for tableview where datasource has to be implemented as cellForRowAtIndexPath works fast and you must return reused cell identifiers quickly. This is a method of datasource of tableview

tableView:willDisplayCell:forRowAtIndexPath is a method of delegate & not datasource. This method is called exactly before loading cells in UITableView bounds.

why does setting a UITableViewCell's color work in willDisplayCell but not in cellForRowAtIndexPath?

The doco for UITableViewCell states that you need to do it in willDisplayCell: (excerpt from the UITableViewCell class reference below). I suspect that because table cells have a content view and various other components that seem to be 'managed' by UIKit, that its doing its own thing with the background color after its set in cellForRowAtIndexPath. You can also use the 'backgroundView' property of a table view cell to control its background.

documentation excerpt:

Note: If you want to change the background color of a cell (by setting the background color of a cell via the backgroundColor property declared by UIView) you must do it in the tableView:willDisplayCell:forRowAtIndexPath: method of the delegate and not in tableView:cellForRowAtIndexPath: of the data source. Changes to the background colors of cells in a group-style table view has an effect in iOS 3.0 that is different than previous versions of the operating system. It now affects the area inside the rounded rectangle instead of the area outside of it.

Proper place to update UITableViewCell content

The statement is wrong.

custom cell appears to ‘randomly change content’ when the table is scrolled

occurs only if

  • dequeueReusableCellWithIdentifier is (mis)used outside cellForRowAtIndexPath.
  • The entire content of the cell is not set reliably to a defined state inside cellForRowAtIndexPath.
  • The content of the cell is manipulated outside cellForRowAtIndexPath.

The developer is strongly discouraged from using any of the three cases.

So it's perfectly fine to both supply the cell and update the content in cellForRowAtIndexPath.

PS: I guess willDisplayCell:forRowAtIndexPath: is a legacy method coming from the cell based NSTableView in macOS where the data source delegate methods don't support to change the cell's appearance.

uitableview willdisplaycell delegate is strange

First get the number of rows in section. Then find the last item

let totalRow = tableView.numberOfRows(inSection: indexPath.section)
if(indexPath.row == totalRow - 1)
{
print("end")
return
}

Custom UITableViewCell from nib in Swift

With Swift 5 and iOS 12.2, you should try the following code in order to solve your problem:

CustomCell.swift

import UIKit

class CustomCell: UITableViewCell {

// Link those IBOutlets with the UILabels in your .XIB file
@IBOutlet weak var middleLabel: UILabel!
@IBOutlet weak var leftLabel: UILabel!
@IBOutlet weak var rightLabel: UILabel!

}

TableViewController.swift

import UIKit

class TableViewController: UITableViewController {

let items = ["Item 1", "Item2", "Item3", "Item4"]

override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UINib(nibName: "CustomCell", bundle: nil), forCellReuseIdentifier: "CustomCell")
}

// MARK: - UITableViewDataSource

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}

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

cell.middleLabel.text = items[indexPath.row]
cell.leftLabel.text = items[indexPath.row]
cell.rightLabel.text = items[indexPath.row]

return cell
}

}

The image below shows a set of constraints that work with the provided code without any constraints ambiguity message from Xcode:

Sample Image



Related Topics



Leave a reply



Submit