I've come across an annoying situation. I've found similar questions, but the answers didn't help me, so I was hoping I could get some advice.
I have a custom UITableViewCell where I'm using a .xib file. I fetch some data when the app loads, and once it's retrieved I reload my tableView. The cells display a picture and some labels, and I need the labels to adjust their size based on the width of the text for the content in the individual cell. Say I have this for cellForRowAt indexPath
:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard
let cell = tableView.dequeueReusableCell(withIdentifier: MyCell.reuseIdentifier, for: indexPath) as? MyCell,
indexPath.row < myDataArray.count
else { return UITableViewCell() }
let dataForCell = myDataArray[indexPath.row]
cell.configure(with: dataForCell)
cell.layoutIfNeeded()
return cell
}
Now in my MyCell.swift
file, inside the configure(with:)
method I set the label texts, then I also call a private method called setWidths()
which uses an extension I added to UILabel
to return to me the width of a label after the text is set - I do some basic calculations to adjust the constraints of the labels how I want.
The only problem I'm having is that when the table view initially loads, the label's widths aren't updating properly, but when I scroll down to the cells that were originally out of frame, they are displayed properly, and then when I scroll back up to the cells that were originally in frame and misaligned, they then also show properly.
I know I've come across issues like this before, but usually calling layoutIfNeeded()
on the cell fixes the issue. It's not this time.
I know that this is connected the the idea of reusable cells and dequeuing, but why is the first group of cells laid out not following the same rules? These are the first cells the user sees, I need them to be correct!
Does anyone have any advice for me?
EDIT
I think I've targeted the issue, however I still don't quite know what to do. I have to adjust my calculated label widths based on the available with of the cell frame. I added some print statements to see if the cell width was changing, and it is. Inside the setWidths()
method I added print(self.frame.width)
and when the tableView first loads it prints out 325.0
for each cell, but then as I scroll and it lays out new cells, it changes to 414.0
(Using iPhone 8 Plus simulator). What's causing the change in the cell's frame width from initial layout to when the cell is reused?