刚学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也是有缺點的。