搜尋

首頁  >  問答  >  主體

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";
}]

希望,各位大神指教!

高洛峰高洛峰2772 天前677

全部回覆(4)我來回復

  • 高洛峰

    高洛峰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
    

    回覆
    0
  • 迷茫

    迷茫2017-04-17 13:40:43

    Q:有沒有方法不計算每個label的寬度並賦值給superview的寬度,而是自動填充superview?
    A:重寫superview的updateConstraints和intrinsicContentSize方法

    回覆
    0
  • 高洛峰

    高洛峰2017-04-17 13:40:43

    1. 一個 containerview 包含3個 label

    2. 這3個 label 不要指定寬度,

    3. 約束 containerview 和 left+right 的邊距約束

    4. 約束 left center right labels 的間距關係

    5. 約束 contrainerview 居中

    回覆
    0
  • 怪我咯

    怪我咯2017-04-17 13:40:43

    我也一直被這個問題困擾, 多個view想要劇中需要外部套用一個View, 如果手動設定計算frame就不會出現這個問題, 可見autolaout也是有缺點的。

    回覆
    0
  • 取消回覆