1

My programmatically generated custom UITableViewCell contains several UILabel that can wrap the text:

newLabel.numberOfLines = 0;
newLabel.lineBreakMode = NSLineBreakByWordWrapping;

I use these cells in a UITableView with the following parameters:

self.tableView.estimatedRowHeight = 120.0;
self.tableView.rowHeight = UITableViewAutomaticDimension;

I therefore expect that the height of cells is automatically adjusted and the UILabel show multiple lines when required.

Because this did not work for newly created cells, I force the UITableView to perform a update in viewDidAppear:

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    if (self.appearsFirstTime) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [self.tableView beginUpdates];
            [self.tableView endUpdates];
            self.appearsFirstTime = NO;
        });
    }
}

This works well for the cells that were generated during the first appearance of the UITableView and thus already existed when updating. However, it does not work for cells which were generated by scrolling at a later time. These later initialized cells have no chance to benefit from the update, and therefore have an incorrect height.

I have found a different approach to solve the problem: https://stackoverflow.com/a/25967370/4943710 But this approach suffers from the fact that the layout process may require several passes. The approach is then working with interim results, which lead to incorrect heights. The result again is missing rows of text. In addition, it seems that the cells lose the ability to adapt in later updates (for example, when changing the interface orientation).

Now my question: How can I make sure that cells generated later (after updating the UITableView) always will be displayed with correct height?

Community
  • 1
  • 1
d2ns
  • 19
  • 3
  • You are not using **storyboard** ? – Gürhan KODALAK May 28 '15 at 15:03
  • Are you using **layoutSubViews** method for **UITableView** ? – Gürhan KODALAK May 28 '15 at 15:06
  • I am using storyboard to instantiate my tableViewController [self.storyboard instantiateViewControllerWithIdentifier:@"identifier"] but I do not use prototypeCells from storyboard. – d2ns May 28 '15 at 15:34
  • I am not using layoutSubviews for my tableView. I use layoutSubviews in my custom cell but not to do any layout, only for the purpose to examine what is going on (logging) – d2ns May 28 '15 at 15:41

2 Answers2

0

I therefore expect that the height of cells is automatically adjusted and the UILabels show multiple lines when required.

Your "therefore" is a little premature. There is another requirement for automatic cell height, which you may not be satisfying: the cell's content view's height must be determined from the inside out by constraints pinned between the content view and its subviews.

Thus, you may have a label in the cell, but if its top and bottom are not pinned by constraints to the top and bottom of the cell's content view, nothing is going to happen. And you, in your question, have not said that they are.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • All necessary constraints exist. After the update, the cell has the correct height. That would not be the case without constraints or with a missing constraint. Only in the case of new cells I get an incorrect height. – d2ns May 28 '15 at 15:46
  • Because the constraints are not correct in the new cells. – matt May 28 '15 at 15:48
  • When I create my cell using initWithStyle, I add all necessary constraints. So all constraints are correct, no matter if new cell or recycled cell. – d2ns May 28 '15 at 15:55
  • Clearly not. If you were doing this correctly, you wouldn't be having the problem you're asking about. – matt May 28 '15 at 15:57
  • Okay. If so, where then the constraints come from, which not I create? If I rotate my device from portrait to landscape which forces my tableView to perform a update (beginUpdates/endUpdates), the cell gets the correct height. In my opinion this is not possible with wrong or missing constraints. – d2ns May 28 '15 at 16:07
  • I think the problem is something like described in http://stackoverflow.com/a/25967370/4943710. The UILabels have not the correct width (and no preferredMaxLayoutWidth). So they can not calculate their height. – d2ns May 28 '15 at 16:15
  • Absolutely. That internal calculation is part of the constraint structure (the internally generated intrinsic content size is used to get the height constraint). See my discussion here of how a label gets its height: http://stackoverflow.com/a/30448659/341994 – matt May 28 '15 at 16:20
  • But how do I give the label the correct width, so that it can calculate its height? left and right constraints are there, only the cell seems not to know its own width. – d2ns May 28 '15 at 16:34
  • Here's a working example: https://github.com/mattneub/Programming-iOS-Book-Examples/tree/master/bk2ch08p424variableHeights/ch21p722variableHeights Download the project and look at the constraints in _Cell.xib_... – matt May 28 '15 at 17:15
0

I have just identified a issues with layout out my custom UITableViewCell which was also caused by multi-line labels set to 0 lines. I fixed it by setting the number of lines to 2, adequate for my needs, and the issue was resolved.

Thanks for highlighting this, we've been trying to fix it for much too long.

Leon
  • 3,614
  • 1
  • 33
  • 46