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 outsidecellForRowAtIndexPath
.- 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:
Related Topics
Open Uitableview Edit Action Buttons Programmatically
Hide Keyboard for Text Field in Swift Programming Language
Create a Copy of a Uiview in Swift
iOS 7 Uitextview Vertical Alignment
How to Get Location User with Cllocationmanager in Swift
How to Export Data to a CSV File with iOS
Objective-C Get a Class Property from String
App Does Not Have Access to Your Photos or Videos iOS 9
iOS - How to Play a Video with Transparency
iOS Open Youtube App with Query (Url Schemes)
How to Present a Uiviewcontroller from Skscene
How to Debug "Terminated Due to Memory Error"
Swift - Get Local Date and Time
Xcode 10.2 with Swift 5.0 Compiler - Protocol Inheritance Issue
Make Segue Programmatically in Swift
Recording to Aac from Remoteio: Data Is Getting Written But File Unplayable