UITableViewCell - constraints only updated after reload
Asked Answered
S

3

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?

Sunn answered 10/2, 2017 at 11:39 Comment(0)
E
10

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

Eldreda answered 17/7, 2017 at 11:8 Comment(0)
K
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];
Karmenkarna answered 10/2, 2017 at 12:12 Comment(9)
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.Sunn
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.Sunn
@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.Karmenkarna
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?Sunn
You have to [someview.superview layoutIfNeeded] set layoutIfNeeded to the superview of view you have changedWoodchuck
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]Woodchuck
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.Sunn
Any solution for this please? I have the same problemThrow
Has a solution for this been found? I'm facing the same issue.Dartboard
C
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()

}
Captivity answered 9/8, 2018 at 10:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.