9

I have a custom UITableViewCell in which I have a UIView that contains multiple subviews. Depending on the cases, I hide some of those views, and I update constraints so that the parent UIView is still centered in my UITableViewCell.

My issue is that, because of the cell reuse, this only works if the cell isn't directly shown (if the cell isn't one of the top cells that appear first in the table). In such cases, when I scroll down, and I scroll back up, it works again. Pictures will help me explain this:

This is what is displayed once the UITableView is loaded for the first time. The first cell is a regular cell with all info, the second cell is the one where the first elements have been hidden.

First view

This is what happens when I scroll down, and then back up.

enter image description here

As you can see, that's exactly what I want. The constraints have been updated correctly, but only once the cell disappeared from the visible screen, and appeared again.

[reviewsAndPriceView setNeedsUpdateConstraints];
[reviewsAndPriceView setNeedsLayout];
[reviewsAndPriceView layoutIfNeeded];
[self updateConstraints];
[self setNeedsUpdateConstraints];
[self setNeedsLayout];
[self layoutIfNeeded];

And all kinds of variations, but it doesn't work. What's the way to achieve this?

el-flor
  • 1,466
  • 3
  • 18
  • 39

3 Answers3

10

I had the same issue. I resolved it by calling cell.layoutIfNeeded() before returning cell in cellForRowAtIndexPath. Now, for me its working fine.

Mike Doe
  • 16,349
  • 11
  • 65
  • 88
Kedar Desai
  • 101
  • 1
  • 3
1

You already know that cells are being reused.

When you scroll some cells are using constraint of previous displayed.

To resolve this call an reset method which will reset all constraint to its default value as assigned in xib.

After this method call your method which is responsible for changing height/width.

And in last call only :

 [self layoutIfNeeded];
Rahul
  • 5,594
  • 7
  • 38
  • 92
  • So where should I reset all constraints? At the very beginning of the cellForIndexPath? I have tried doing this, but it doesn't change anything. – el-flor Feb 10 '17 at 12:19
  • This doesn't seem to resolve it either. So after generating the cell I should reset all my constraints to their original value and then rechange them? The weird part is that resetting them doesn't change anything either. – el-flor Feb 10 '17 at 12:45
  • @bloemy your cells are only created once. If at a time visible cells are 5 then only 5 cells are being created. when you scroll then thses cells are reused. And constraint of these are updated now. Got my point. – Rahul Feb 10 '17 at 12:50
  • I understand that but the initialization of my TableViewCell is made in my custom class. The [tableView dequeueCellWith...] call is made in another class, my main class which calls my custom cell class. I don't want to make any changes in my main class. Is there no way to resolve this directly in my subclass? – el-flor Feb 10 '17 at 12:58
  • You have to `[someview.superview layoutIfNeeded]` set `layoutIfNeeded` to the superview of view you have changed – Nazir Feb 10 '17 at 15:04
  • Some more points: if your `subviews` in your `UIView` are changing their positions or sizes you have to set `[UIView layoutIfNeeded]`, if in the case of subview changes the UIView is also resized `[UITableViewCell layoutIfNeeded]` – Nazir Feb 10 '17 at 15:09
  • Thanks for the info @Nazir. I don't know why this doesn't help. I'm literally doing all three things you said (the UIView itself, the UIView superview and the Cell layoutIfNeeded), but it's still not resizing on the first launch...It only works after scrolling. – el-flor Feb 10 '17 at 16:31
  • Any solution for this please? I have the same problem – Lohith Korupolu Jun 28 '17 at 05:43
  • Has a solution for this been found? I'm facing the same issue. – Luke Irvin May 30 '19 at 14:53
1

I designed the collectoin view cell using the multiplier . and some of the parts of cells were not correctly displayed on the real device . Using the 3 methode below and reloading the collectoin view at certain times constrains set in the storyboard are correctly displayed on the real device.

(You can use this solution both in the collection view and in the table view)

override func viewDidAppear(_ animated: Bool) {

        colLessons.reloadData()
        colLessons.setNeedsLayout()
        colLessons.layoutIfNeeded()
        colLessons.reloadData()

}

func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {

        colLessons.reloadData()
        colLessons.setNeedsLayout()
        colLessons.layoutIfNeeded()
        colLessons.reloadData()

}

func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {

        colLessons.reloadData()
        colLessons.setNeedsLayout()
        colLessons.layoutIfNeeded()
        colLessons.reloadData()

}
Hamid Reza Ansari
  • 1,107
  • 13
  • 16