iOS 8 UILabel intrinsicContentSize打破布局约束

时间:2015-01-12 18:31:56

标签: ios autolayout

我有一个非常简单的自定义UITableViewCell子类,其中包含UISwitchUIImageViewUILabel。所有这些都是单元格contentView的子视图,并使用AutoLayout进行布局。所有子视图都以Y为中心,然后我创建了一系列左右边缘约束来水平排列它们。 UILabel是最右边的项目,应缩放以适合其左侧UIImageView的右边缘和其超级视图的右边缘。当文本太长而无法适应时,它应该截断。当我使用iOS 7.1模拟器进行测试时,这可以正常工作。但是,在iOS 8.1上,当标签中的文本太长而无法放入分配的空间时,标签会将UIImageView推向其左侧的位置。我过去从未遇到UILabel这个问题。

编辑:我应该提到我在运行时没有出现自动布局错误。

以下是截图和我的代码:

以下是iOS 7上的正确行为:

Working version on iOS 7.1

这是我在iOS 8上获得的:

Bad iOS 8.1 layout

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];

    self.backgroundColor = [UIColor whiteColor];
    self.contentView.backgroundColor = [UIColor whiteColor];

    UISwitch *filterSwitch = [[UISwitch alloc] init];
    _filterSwitch = filterSwitch;
    filterSwitch.translatesAutoresizingMaskIntoConstraints = NO;
    [self.contentView addSubview:filterSwitch];
    [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:filterSwitch
                                                                 attribute:NSLayoutAttributeCenterY
                                                                 relatedBy:NSLayoutRelationEqual
                                                                    toItem:self.contentView
                                                                 attribute:NSLayoutAttributeCenterY
                                                                multiplier:1.0
                                                                  constant:0.0]];
    [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:filterSwitch
                                                                 attribute:NSLayoutAttributeLeft
                                                                 relatedBy:NSLayoutRelationEqual
                                                                    toItem:self.contentView
                                                                 attribute:NSLayoutAttributeLeft
                                                                multiplier:1.0
                                                                  constant:10.0]];

    UIImageView *filterImageView = [[UIImageView alloc] init];
    _filterImageView = filterImageView;
    filterImageView.translatesAutoresizingMaskIntoConstraints = NO;
    filterImageView.backgroundColor = [UIColor redColor];
    filterImageView.contentMode = UIViewContentModeScaleAspectFit;
    [self.contentView addSubview:filterImageView];
    [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:filterImageView
                                                                 attribute:NSLayoutAttributeCenterY
                                                                 relatedBy:NSLayoutRelationEqual
                                                                    toItem:self.contentView
                                                                 attribute:NSLayoutAttributeCenterY
                                                                multiplier:1.0
                                                                  constant:0.0]];
    [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:filterImageView
                                                                 attribute:NSLayoutAttributeHeight
                                                                 relatedBy:NSLayoutRelationEqual
                                                                    toItem:nil
                                                                 attribute:NSLayoutAttributeNotAnAttribute
                                                                multiplier:1.0
                                                                  constant:30.0]];
    [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:filterImageView
                                                                 attribute:NSLayoutAttributeWidth
                                                                 relatedBy:NSLayoutRelationEqual
                                                                    toItem:filterImageView
                                                                 attribute:NSLayoutAttributeHeight
                                                                multiplier:1.0
                                                                  constant:0.0]];
    [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:filterImageView
                                                                 attribute:NSLayoutAttributeLeft
                                                                 relatedBy:NSLayoutRelationEqual
                                                                    toItem:filterSwitch
                                                                 attribute:NSLayoutAttributeRight
                                                                multiplier:1.0
                                                                  constant:8.0]];

    UILabel *filterLabel = [[UILabel alloc] init];
    _filterLabel = filterLabel;
    filterLabel.translatesAutoresizingMaskIntoConstraints = NO;
    filterLabel.font = [UIFont fontWithName:@"Avenir-Medium" size:14.0];
    filterLabel.textColor = [UIColor colorWithWhite:0.25 alpha:1.0];
    filterLabel.textAlignment = NSTextAlignmentLeft;
    filterLabel.lineBreakMode = NSLineBreakByTruncatingTail;
    [self.contentView addSubview:filterLabel];
    [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:filterLabel
                                                                 attribute:NSLayoutAttributeCenterY
                                                                 relatedBy:NSLayoutRelationEqual
                                                                    toItem:self.contentView
                                                                 attribute:NSLayoutAttributeCenterY
                                                                multiplier:1.0
                                                                  constant:0.0]];
    [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:filterLabel
                                                                 attribute:NSLayoutAttributeLeft
                                                                 relatedBy:NSLayoutRelationEqual
                                                                    toItem:filterImageView
                                                                 attribute:NSLayoutAttributeRight
                                                                multiplier:1.0
                                                                  constant:8.0]];
    [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:filterLabel
                                                                 attribute:NSLayoutAttributeRight
                                                                 relatedBy:NSLayoutRelationEqual
                                                                    toItem:self.contentView
                                                                 attribute:NSLayoutAttributeRight
                                                                multiplier:1.0
                                                                  constant:-10.0]];

    return self;
}

1 个答案:

答案 0 :(得分:3)

据推测,开关和标签的水平抗压强度优先级相同。因此,布局不明确(不会自动检测,因此在运行时没有错误)。当两者都不能适合可用的宽度时,它是任意的,将被压缩。所以,你在iOS 7上只是幸运(或不幸,取决于你如何看待它)。

将标签的水平抗压力设置为低于其他两个视图的水平抗压力,以便先压缩。

我刚试过:如果你设置相同的情况 - H:|-[switch]-[image(==30)]-[label]-| - 在IB的视图中并将标签的文本设置得足够长,IB会告诉你模糊问题。