刚学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)]];
枚举类型参数中:
c
typedef 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,该如何使用?每次使用都回报错!
c
NSInvalidArgumentException|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"; }]
希望,各位大神指教!
高洛峰2017-04-17 13:40:43
刚刚算是勉强自己解决了:方法比较笨,即用一个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
迷茫2017-04-17 13:40:43
Q:有没有方法不计算每个label的宽度并赋值给superview的宽度,而是自动填充superview?
A:重写superview的updateConstraints和intrinsicContentSize方法
高洛峰2017-04-17 13:40:43
一个 containerview 包含3个 label
这3个 label 不要指定宽度,
约束 containerview 和 left+right 的边距约束
约束 left center right labels 的间距关系
约束 contrainerview 居中
怪我咯2017-04-17 13:40:43
我也一直被这个问题困扰, 多个view想要剧中需要外部套用一个View, 如果手动设置计算frame就不会出现这个问题, 可见autolaout也是有缺点的。