UILabel in UITableViewCell with auto layout has wrong height

前端 未结 6 945
孤独总比滥情好
孤独总比滥情好 2021-02-01 19:00

I have a UITableView with cells that have a fixed height of 100 points. The cells are created in a xib file that uses 3 constraints to pin a UILabel to

6条回答
  •  臣服心动
    2021-02-01 19:46

    Since you're constraining the label's width, the intrinsicContentSize honors that width and adjusts the height. And this sets up a chicken and egg problem:

    1. The cell's Auto Layout result depends on the label's intrinsicContentSize
    2. The label's intrinsicContentSize depends on the label's width
    3. The label's width depends on the cell's Auto Layout result

    So what happens is that the cell's layout is only calculated once in which (2) is based on the static width in the XIB file and this results in the wrong label height.

    You can solve this by iterating. That is, repeat the Auto Layout calculation after the label's width has been set by the first calculation. Something like this in your custom cell will work:

    - (void)drawRect:(CGRect)rect
    {
        CGSize size = self.myLabel.bounds.size;
        // tell the label to size itself based on the current width
        [self.myLabel sizeToFit];
        if (!CGSizeEqualToSize(size, self.myLabel.bounds.size)) {
            [self setNeedsUpdateConstraints];
            [self updateConstraintsIfNeeded];
        }
        [super drawRect:rect];
    }
    

    original solution does not work reliably:

    - (void)layoutSubviews
    {
        [super layoutSubviews];
        // check for need to re-evaluate constraints on next run loop
        // cycle after the layout has been finalized
        dispatch_async(dispatch_get_main_queue(), ^{
            CGSize size = self.myLabel.bounds.size;
            // tell the label to size itself based on the current width
            [self.myLabel sizeToFit];
            if (!CGSizeEqualToSize(size, self.myLabel.bounds.size)) {
                [self setNeedsUpdateConstraints];
                [self updateConstraintsIfNeeded];
            }
        });
    }
    

提交回复
热议问题