search

Home  >  Q&A  >  body text

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

希望,各位大神指教!

高洛峰高洛峰2886 days ago701

reply all(4)I'll reply

  • 高洛峰

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

    I just forced myself to solve it: the method is rather stupid, that is, use a backview to contain 3 labels, then calculate the width of the 3 labels and assign them to the outer backview, and finally center the backview to complete the 3 labels. The label is displayed in the center! If there is a better method, please add it and discuss it!

    The hierarchy is:

    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)]];
    

    Here comes the question:

    Is there a way not to calculate the width of each label and assign it to the width of the superview, but to automatically fill the superview!

    PS: When I was testing, I found that if the width of the backview is not set, it will be the width of the entire screen!


    Updated on 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
    

    reply
    0
  • 迷茫

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

    Q: Is there a way to automatically fill the superview without calculating the width of each label and assigning it to the width of the superview?
    A: Override superview’s updateConstraints and intrinsicContentSize methods

    reply
    0
  • 高洛峰

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

    1. A containerview contains 3 labels

    2. Do not specify the width for these three labels,

    3. Constrain containerview and left+right margin constraints

    4. Constrain the spacing relationship between left center right labels

    5. Constrain contrainerview to center

    reply
    0
  • 怪我咯

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

    I have also been troubled by this problem. If I want to use multiple views in the play, I need to apply a View externally. If I manually set the calculation frame, this problem will not occur. It can be seen that autolaout also has shortcomings.

    reply
    0
  • Cancelreply