首页 > iOS:autolayout,多个label如何设置居中显示?

iOS:autolayout,多个label如何设置居中显示?

刚学autolayout,关于这个问题,一直没搞清楚!

c[backview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[lab_before][lab_middle][lab_after]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(lab_before,lab_middle,lab_after)]];

枚举类型参数中:

ctypedef NS_OPTIONS(NSUInteger, NSLayoutFormatOptions) {
    NSLayoutFormatAlignAllLeft = (1 << NSLayoutAttributeLeft),
    NSLayoutFormatAlignAllRight = (1 << NSLayoutAttributeRight),
    NSLayoutFormatAlignAllTop = (1 << NSLayoutAttributeTop),
    NSLayoutFormatAlignAllBottom = (1 << NSLayoutAttributeBottom),
    NSLayoutFormatAlignAllLeading = (1 << NSLayoutAttributeLeading),
    NSLayoutFormatAlignAllTrailing = (1 << NSLayoutAttributeTrailing),
    NSLayoutFormatAlignAllCenterX = (1 << NSLayoutAttributeCenterX),
    NSLayoutFormatAlignAllCenterY = (1 << NSLayoutAttributeCenterY),
    NSLayoutFormatAlignAllBaseline = (1 << NSLayoutAttributeBaseline),
    NSLayoutFormatAlignAllLastBaseline = NSLayoutFormatAlignAllBaseline,
    NSLayoutFormatAlignAllFirstBaseline NS_ENUM_AVAILABLE_IOS(8_0) = (1 << NSLayoutAttributeFirstBaseline),

    NSLayoutFormatAlignmentMask = 0xFFFF,

参数中的NSLayoutFormatAlignAllCenterX,该如何使用?每次使用都回报错!

附上报错信息:

cNSInvalidArgumentException|Unable to parse constraint format: \nOptions mask required views to be aligned on a horizontal edge, which is not allowed for layout that is also horizontal. \nH:|[lab_before][lab_middle][lab_after]| \n                           ^|(\n    \"4   libc++abi.dylib                     0x0000000192c65bb4 <redacted> + 16\",\n    \"5   libc++abi.dylib                     0x0000000192c65478 <redacted> + 0\",\n    \"6   libobjc.A.dylib                     0x0000000193478204 <redacted> + 0\",\n    \"7   Foundation                          0x0000000183ce11cc <redacted> + 0\",\n    \"8   Foundation                          0x0000000183b6bf44 <redacted> + 1296\"\n)|iPhone OS|8.1|1.0.0|iPhone7,1";
}]

希望,各位大神指教!


Q:有没有方法不计算每个label的宽度并赋值给superview的宽度,而是自动填充superview?
A:重写superview的updateConstraints和intrinsicContentSize方法


  1. 一个 containerview 包含3个 label

  2. 这3个 label 不要指定宽度,

  3. 约束 containerview 和 left+right 的边距约束

  4. 约束 left center right labels 的间距关系

  5. 约束 contrainerview 居中


刚刚算是勉强自己解决了:方法比较笨,即用一个backview来包含3个label,然后计算3个label的宽度并赋值给外层的backview,最后把backview居中显示,就完成了3个label的居中显示!如果有更好的方法,欢迎补充,讨论!

层次结构是:

c- view
    -backview
        -label1
        -label2
        -label3
c// 设置水平布局
    [backview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[lab_before]-[lab_middle]-[lab_after]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(lab_before,lab_middle,lab_after)]];
c// 设置backview宽度
    [view addConstraint:[NSLayoutConstraint constraintWithItem:backview attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:dynaContentView attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:before_width+middle_width+after_width]];

    // 设置backview居中显示
    [view addConstraint:[NSLayoutConstraint constraintWithItem:backview attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:dynaContentView attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0.0]];

    // 设置backview的高度
    [view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[backview(==34)]-0-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(backview)]];

问题来了:

有没有方法不计算每个label的宽度并赋值给superview的宽度,而是自动填充superview!

PS:我在测试的时候,发现不设置backview的宽度,就是整个屏幕的宽度!


2015/03/01更新:

c@interface CustomView1 : UIView
@property(nonatomic, strong) UILabel *label1;
@property(nonatomic, strong) UILabel *label2;
@end
c@implementation CustomView1

-(id)init{
    self = [super init];
    if(self){
        _label1 = [UILabel new];
        _label1.text = @"AAAAAA121212121";
        _label1.textColor = [UIColor blackColor];
        _label1.translatesAutoresizingMaskIntoConstraints = NO;
        [self addSubview:_label1];

        _label2 = [UILabel new];
        _label2.text = @"BBBBBB";
        _label2.textColor = [UIColor orangeColor];
        _label2.translatesAutoresizingMaskIntoConstraints = NO;
        [self addSubview:_label2];

    }
    return self;
}

- (void)updateConstraints{
    NSDictionary *views = NSDictionaryOfVariableBindings(_label1,_label2);

    // label1的宽高
    [self addConstraint:[NSLayoutConstraint constraintWithItem:_label1 attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:[_label1 intrinsicContentSize].width]];

    [self addConstraint:[NSLayoutConstraint constraintWithItem:_label1 attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:[_label1 intrinsicContentSize].height]];

    // label2的宽高
    [self addConstraint:[NSLayoutConstraint constraintWithItem:_label2 attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:[_label2 intrinsicContentSize].width]];

    [self addConstraint:[NSLayoutConstraint constraintWithItem:_label2 attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:[_label2 intrinsicContentSize].height]];

    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_label1][_label2]|" options:NSLayoutFormatAlignAllBottom metrics:nil views:views]];

    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[_label1]|" options:0 metrics:nil views:views]];

    [super updateConstraints];
}

- (CGSize)intrinsicContentSize{
    CGSize l1size = [_label1 intrinsicContentSize];
    CGSize l2size = [_label2 intrinsicContentSize];

    return CGSizeMake(l1size.width + l2size.width, l1size.height);
}

@end

我也一直被这个问题困扰, 多个view想要剧中需要外部套用一个View, 如果手动设置计算frame就不会出现这个问题, 可见autolaout也是有缺点的。

【热门文章】
【热门文章】