UITableViewCell custom software auto-layout does not work when scrolling

I am trying to use the new iOS 6 auto-layout feature in a custom UITableViewCell that was implemented programmatically. I added addConstraint calls, and it works correctly first - until I scroll. When I return to the camera after scrolling, the layout is broken. Destroyed, I mean that the fields between the fields are incorrect (too large, which significantly exceeds the cell size). I suppose this has something to do with the dequeueReusableCellWithIdentifier method, leaving me with a dirty cell, just like you need to reinitialize the fields inside the cells, but I can't do anything to persuade it to display correctly again. I tried calling [self.contentView updateConstraints] before returning the cell. I tried to destroy the constraints and recreate them. Not only does this not work, but if he tried layoutSubviews, it freezes in an infinite loop. Any ideas?

Here is the code for setting limits. It is located in initWithStyle: reuseIdentifier:

[self.completedLabel setTranslatesAutoresizingMaskIntoConstraints:NO]; [self.nextSetHeaderLabel setTranslatesAutoresizingMaskIntoConstraints:NO]; [self.nextSetDetailLabel setTranslatesAutoresizingMaskIntoConstraints:NO]; [self.youWillLearnHeaderLabel setTranslatesAutoresizingMaskIntoConstraints:NO]; [self.youWillLearnDetailLabel setTranslatesAutoresizingMaskIntoConstraints:NO]; [self.contentView removeConstraints:[self.contentView constraints]]; NSDictionary *views = NSDictionaryOfVariableBindings(_completedLabel, _nextSetHeaderLabel, _nextSetDetailLabel, _youWillLearnHeaderLabel, _youWillLearnDetailLabel); [self.contentView addConstraints: [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-5-[_completedLabel]-5-|" options:0 metrics:nil views:views]]; [self.contentView addConstraints: [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-5-[_nextSetHeaderLabel]-5-|" options:0 metrics:nil views:views]]; [self.contentView addConstraints: [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-5-[_nextSetDetailLabel]-5-|" options:0 metrics:nil views:views]]; [self.contentView addConstraints: [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-5-[_youWillLearnHeaderLabel]-5-|" options:0 metrics:nil views:views]]; [self.contentView addConstraints: [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-5-[_youWillLearnDetailLabel]-4-|" options:0 metrics:nil views:views]]; [self.contentView addConstraints: [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-5-[_completedLabel]-12-[_nextSetHeaderLabel]-0-[_nextSetDetailLabel]-12-[_youWillLearnHeaderLabel]-0-[_youWillLearnDetailLabel(>=20)]-1-|" options:0 metrics:nil views:views]]; 
+2
source share
2 answers

I ran into this problem. If I didn’t take the cells, everything would seem to work - scrolling, rotating, etc. However, if I deleted the cells, then the layout began to mess up. The only way to make it work is to override the prepareForReuse method. In this method

  • 1. delete all user subtitles
    2. Remove all restrictions associated with these areas from the contentView
    3. Add sub-elections and constraints again

 -(void) prepareForReuse { [self removeCustomSubviewsFromContentView]; [self.contentView removeConstraints:self.constraints] //self.constraits holds all the added constraints [self setupSubviewsInContentView]; [self addConstraintsToContentView]; } 

If there is a better way to do this, I really want to learn too :) I believe that the advantage of dequeing is that the tableView should not contain a large number of cells in memory - but using this method, you need to go through the cost of essentially setting up the cell each time you change.

+1
source

I had a similar problem, if anyone is interested, I found a solution, see this question

What I've done:

 - (void)awakeFromNib { [super awakeFromNib]; for (NSLayoutConstraint *cellConstraint in self.constraints) { [self removeConstraint:cellConstraint]; id firstItem = cellConstraint.firstItem == self ? self.contentView : cellConstraint.firstItem; id seccondItem = cellConstraint.secondItem == self ? self.contentView : cellConstraint.secondItem; NSLayoutConstraint* contentViewConstraint = [NSLayoutConstraint constraintWithItem:firstItem attribute:cellConstraint.firstAttribute relatedBy:cellConstraint.relation toItem:seccondItem attribute:cellConstraint.secondAttribute multiplier:cellConstraint.multiplier constant:cellConstraint.constant]; [self.contentView addConstraint:contentViewConstraint]; } } 
0
source

Source: https://habr.com/ru/post/1487233/


All Articles