• NSLayoutConstraint,系统的布局类

/**
 系统默认添加约束的方法,它是NSLayoutConstraint的类方法

 @param view1 想要添加约束的控件
 @param attr1 想要添加约束的方向
 @param relation 传入与约束值的关系,大于、等于还是小于
 @param view2 被参照对象
 @param attr2 被参照对象所被参照的方向,如顶部、左边、右边等
 @param multiplier 间距倍数关系
 @param c 最终的差值
 @return NSLayoutConstraint对象
 */
//+(instancetype)constraintWithItem:(id)view1
//                        attribute:(NSLayoutAttribute)attr1
//                        relatedBy:(NSLayoutRelation)relation
//                           toItem:(nullable id)view2
//                        attribute:(NSLayoutAttribute)attr2
//                       multiplier:(CGFloat)multiplier
//                         constant:(CGFloat)c
-(void)sysAutolayout{
    /////////////////////////////////////////// red view ////////////////////////////////////////////////
    UIView *redView = [[UIView alloc] init];
    [self.view addSubview:redView];
    redView.backgroundColor = [UIColor redColor];

    //⚠️:一定要加上这句代码,否则添加的约束会有冲突
    redView.translatesAutoresizingMaskIntoConstraints = NO;

    //左边的约束
    NSLayoutConstraint *redLeftCons = [NSLayoutConstraint constraintWithItem:redView
                                                                   attribute:NSLayoutAttributeLeft
                                                                   relatedBy:NSLayoutRelationEqual
                                                                      toItem:self.view
                                                                   attribute:NSLayoutAttributeLeft
                                                                  multiplier:1
                                                                    constant:20];
//    [self.view addConstraint:redLeftCons];
    redLeftCons.active = YES;//这是官方建议的方法

    //底部的约束
    NSLayoutConstraint *redBottomCons = [NSLayoutConstraint constraintWithItem:redView
                                                                     attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual
                                                                        toItem:self.view
                                                                     attribute:NSLayoutAttributeBottom
                                                                    multiplier:1
                                                                      constant:-20];
    //⚠️:只在没有参照控件时(即toItem为nil),约束才添加到自己身上,不然添加到父视图上
//    [self.view addConstraint:redBottomCons];
    redBottomCons.active = YES;

    //宽度约束
    //可以参照其他控件设置约束,如下:
//    [NSLayoutConstraint constraintWithItem:redView
//                                 attribute:NSLayoutAttributeWidth
//                                 relatedBy:NSLayoutRelationEqual
//                                    toItem:self.view
//                                 attribute:NSLayoutAttributeWidth
//                                multiplier:0.5
//                                  constant:0];

    //也可以不参照其他控件
    NSLayoutConstraint *redWidthCons = [NSLayoutConstraint constraintWithItem:redView
                                                                   attribute:NSLayoutAttributeWidth
                                                                   relatedBy:NSLayoutRelationEqual
                                                                      toItem:nil
                                                                   attribute:kNilOptions
                                                                  multiplier:1.0
                                                                    constant:50];
    //这里没有参照控件,所以约束添加到自己身上
//    [redView addConstraint:redWidthCons];
    redWidthCons.active = YES;



    //长度约束,同宽度约束
    NSLayoutConstraint *redHeightCons = [NSLayoutConstraint constraintWithItem:redView
                                                                     attribute:NSLayoutAttributeHeight
                                                                     relatedBy:NSLayoutRelationEqual
                                                                        toItem:nil
                                                                     attribute:kNilOptions
                                                                    multiplier:1.0
                                                                      constant:40];
//    [redView addConstraint:redHeightCons];
    redHeightCons.active = YES;

    /////////////////////////////////////////// blue view ////////////////////////////////////////////////
    UIView *blueView = [[UIView alloc] init];
    [self.view addSubview:blueView];
    blueView.backgroundColor = [UIColor blueColor];
    _blueView = blueView;

    blueView.translatesAutoresizingMaskIntoConstraints = NO;
    NSLayoutConstraint *blueLeftCons = [NSLayoutConstraint constraintWithItem:blueView
                                                                    attribute:NSLayoutAttributeLeft
                                                                    relatedBy:NSLayoutRelationEqual
                                                                       toItem:redView
                                                                    attribute:NSLayoutAttributeRight
                                                                   multiplier:1
                                                                     constant:10];
    [self.view addConstraint:blueLeftCons];

    NSLayoutConstraint *blueBottomCons = [NSLayoutConstraint constraintWithItem:blueView
                                                                      attribute:NSLayoutAttributeBottom
                                                                      relatedBy:NSLayoutRelationEqual
                                                                         toItem:redView
                                                                      attribute:NSLayoutAttributeBottom
                                                                     multiplier:1
                                                                       constant:0];
    [self.view addConstraint:blueBottomCons];

    NSLayoutConstraint *blueWidthCons = [NSLayoutConstraint constraintWithItem:blueView
                                                                     attribute:NSLayoutAttributeWidth
                                                                     relatedBy:NSLayoutRelationEqual
                                                                        toItem:nil
                                                                     attribute:kNilOptions
                                                                    multiplier:1
                                                                      constant:50];
    [blueView addConstraint:blueWidthCons];

    NSLayoutConstraint *blueHeightCons = [NSLayoutConstraint constraintWithItem:blueView
                                                                      attribute:NSLayoutAttributeHeight
                                                                      relatedBy:NSLayoutRelationEqual
                                                                         toItem:nil
                                                                      attribute:kNilOptions
                                                                     multiplier:1
                                                                       constant:50];
    [blueView addConstraint:blueHeightCons];

    /////////////////////////////////////////// yellow view ////////////////////////////////////////////////
    UIView *yellowView = [[UIView alloc] init];
    [self.view addSubview:yellowView];
    yellowView.backgroundColor = [UIColor yellowColor];

    yellowView.translatesAutoresizingMaskIntoConstraints = NO;
    NSLayoutConstraint *yellowLeftCons = [NSLayoutConstraint constraintWithItem:yellowView
                                                                    attribute:NSLayoutAttributeLeft
                                                                    relatedBy:NSLayoutRelationEqual
                                                                       toItem:blueView
                                                                    attribute:NSLayoutAttributeRight
                                                                   multiplier:1
                                                                     constant:10];
    [self.view addConstraint:yellowLeftCons];

    NSLayoutConstraint *yellowBottomCons = [NSLayoutConstraint constraintWithItem:yellowView
                                                                      attribute:NSLayoutAttributeBottom
                                                                      relatedBy:NSLayoutRelationEqual
                                                                         toItem:redView
                                                                      attribute:NSLayoutAttributeBottom
                                                                     multiplier:1
                                                                       constant:0];
    [self.view addConstraint:yellowBottomCons];

    NSLayoutConstraint *yellowWidthCons = [NSLayoutConstraint constraintWithItem:yellowView
                                                                     attribute:NSLayoutAttributeWidth
                                                                     relatedBy:NSLayoutRelationEqual
                                                                        toItem:nil
                                                                     attribute:kNilOptions
                                                                    multiplier:1
                                                                      constant:50];
    [yellowView addConstraint:yellowWidthCons];

    NSLayoutConstraint *yellowHeightCons = [NSLayoutConstraint constraintWithItem:yellowView
                                                                      attribute:NSLayoutAttributeHeight
                                                                      relatedBy:NSLayoutRelationEqual
                                                                         toItem:nil
                                                                      attribute:kNilOptions
                                                                     multiplier:1
                                                                       constant:50];
    [yellowView addConstraint:yellowHeightCons];

    //低优先级的约束
    NSLayoutConstraint *yellowLeftCons_1 = [NSLayoutConstraint constraintWithItem:yellowView
                                                                        attribute:NSLayoutAttributeLeft
                                                                        relatedBy:NSLayoutRelationEqual
                                                                           toItem:redView
                                                                        attribute:NSLayoutAttributeRight
                                                                       multiplier:1
                                                                         constant:10];
    //优先级的范围时0-1000,默认是1000
    //数字越大,优先级越高
    //优先级相同时,会造成约束冲突
    yellowLeftCons_1.priority = 250;//此时优先级低于yellowLeftCons,不执行
    [self.view addConstraint:yellowLeftCons_1];

    [self.view removeConstraint:yellowLeftCons_1];
}
  • VFL
/**
 VFL创建约束的API

 @param format 传入某种格式构成的字符串,用以表达需要添加的约束,如@"H:|-margin-[redView(50)]"表示:水平方向上,redview与父控件左边缘保持"margin"间距,redview的宽度为50
 @param opts 对齐方式,相对于format中所有视图的对齐约束,如果format只有一个view时,可以不设置
 @param metrics 一般传入以间距为key的字典,如:@{@"margin":@20},key要与format参数里所填写的"margin"相同
 @param views 传入约束中提到的view,也是字典,如:@{@"redView":redView},key要与format参数里所填写的"redView"相同
 @return 返回约束的数组
 */
//+ (NSArray *)constraintsWithVisualFormat:(NSString *)format options:(NSLayoutFormatOptions)opts metrics:(NSDictionary *)metrics views:(NSDictionary *)views{}
//vfl是基于NSLayoutConstraint的一种自动布局方式

//format 语法:
//1.每句的前面都要加@"H:"或者@"V:",分别代表着水平和垂直方向
//2.@"|"代表着边界
//3.@"-"用来表示间隙,一般以这样的形式出现@"-20-",也可以先填写标示@"-margin-",之后通过metrics赋值
//4.@"[]"用来存放需要添加约束的view,想要直接设置宽高就这样[redView(50)]

//示例
//H:[cancelButton(72)]-12-[acceptButton(50)]
//cancelButton宽72,acceptButton宽50,它们之间间距12
//
//H:[wideView(>=60@700)]
//wideView宽度大于等于60point,该约束条件优先级为700(优先级最大值为1000,优先级越高的约束条件越先被满足)
//
//V:[redBox][yellowBox(==redBox)]
//垂直方向上,先有一个redBox,其下方紧接一个高度等于redBox高度的yellowBox
//
//H:|-10-[Find]-[FindNext]-[FindField(>=20)]-|
//水平方向上,Find距离父view左边缘间隔10,之后是FindNext距离Find间隔默认宽度;再之后是宽度不小于20的FindField,它和FindNext以及父view右边边缘的间距都是默认宽度。(竖线“|”表示superview的边缘)。
-(void)vflAutolayout{
    UIView *redView = [[UIView alloc] init];
    [self.view addSubview:redView];
    redView.backgroundColor = [UIColor redColor];

    redView.translatesAutoresizingMaskIntoConstraints = NO;

    //这个方法会自动把传入的参数以字典的形式返回,字典的key就是其本身的名字
    NSDictionary *redViewInfo = NSDictionaryOfVariableBindings(redView);

    NSString *hFormat = @"H:|-margin-[redView(redWidth)]";
    NSArray *hCons = [NSLayoutConstraint constraintsWithVisualFormat:hFormat
                                                             options:kNilOptions
                                                             metrics:@{@"margin":@20,@"redWidth":@50}
                                                               views:redViewInfo];
//    [self.view addConstraints:hCons];
    [NSLayoutConstraint activateConstraints:hCons];

    NSString *vFormat = @"V:|-margin-[redView(redHeight)]";
    NSArray *vCons = [NSLayoutConstraint constraintsWithVisualFormat:vFormat
                                                             options:kNilOptions
                                                             metrics:@{@"margin":@20,@"redHeight":@100}
                                                               views:redViewInfo];
//    [self.view addConstraints:vCons];
    [NSLayoutConstraint activateConstraints:vCons];
}

-(void)vflAutolayout_complex{
    UIView *redView = [[UIView alloc] init];
    [self.view addSubview:redView];
    redView.backgroundColor = [UIColor redColor];
    redView.translatesAutoresizingMaskIntoConstraints = NO;

    UIView *blueView = [[UIView alloc] init];
    [self.view addSubview:blueView];
    blueView.backgroundColor = [UIColor blueColor];
    _blueView = blueView;
    blueView.translatesAutoresizingMaskIntoConstraints = NO;


    UIView *yellowView = [[UIView alloc] init];
    [self.view addSubview:yellowView];
    yellowView.backgroundColor = [UIColor yellowColor];
    yellowView.translatesAutoresizingMaskIntoConstraints = NO;

    //////////////////////////////////////////////////////////////
    //这个方法会自动把传入的参数以字典的形式返回,字典的key就是其本身的名字
    NSDictionary *viewInfo = NSDictionaryOfVariableBindings(redView,blueView,yellowView);
    NSDictionary *metrics = @{@"margin":@20};
    NSString *hConsFormat = @"H:|-margin-[redView(50)]-margin-[blueView(==redView)]-margin-[yellowView(==redView)]";
    NSArray *hCons = [NSLayoutConstraint constraintsWithVisualFormat:hConsFormat
                                                             options:NSLayoutFormatAlignAllTop | NSLayoutFormatAlignAllBottom
                                                             metrics:metrics
                                                               views:viewInfo];
    [NSLayoutConstraint activateConstraints:hCons];

    //设置约束的优先级,需要明确是哪个约束需要设置优先级
    NSString *hConsFormat_1 = @"H:|-margin-[redView(50)]-margin@250-[yellowView(==redView)]";
    NSArray *hCons_1 = [NSLayoutConstraint constraintsWithVisualFormat:hConsFormat_1 options:NSLayoutFormatAlignAllTop | NSLayoutFormatAlignAllBottom metrics:metrics views:viewInfo];
    [NSLayoutConstraint activateConstraints:hCons_1];

    NSString *vConsFormat = @"V:|-margin-[redView(50)]";
    NSArray *vCons = [NSLayoutConstraint constraintsWithVisualFormat:vConsFormat
                                                             options:kNilOptions
                                                             metrics:metrics
                                                               views:viewInfo];
    [NSLayoutConstraint activateConstraints:vCons];

}
  • masonry
-(void)masonry_autolayout{
    UIView *redView = [[UIView alloc] init];
    [self.view addSubview:redView];
    redView.backgroundColor = [UIColor redColor];
    _redView = redView;

    UIView *blueView = [[UIView alloc] init];
    [self.view addSubview:blueView];
    blueView.backgroundColor = [UIColor blueColor];
    _blueView = blueView;


    UIView *yellowView = [[UIView alloc] init];
    [self.view addSubview:yellowView];
    yellowView.backgroundColor = [UIColor yellowColor];
    _yellowView = yellowView;

    [redView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.leading.equalTo(self.view).offset(20);
        make.width.height.equalTo(@50);
    }];

    [blueView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.leading.mas_equalTo(redView.mas_trailing).offset(10);
        make.top.width.height.equalTo(redView);
    }];

//    [yellowView mas_makeConstraints:^(MASConstraintMaker *make) {
//        make.top.width.height.equalTo(redView);
//        make.leading.mas_equalTo(blueView.mas_trailing).offset(10);
//        make.leading.mas_equalTo(redView.mas_trailing).offset(10).priorityLow();
//    }];

    [yellowView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.width.height.equalTo(redView);
        self.leftCons = make.leading.mas_equalTo(blueView.mas_trailing).offset(10);
//        make.leading.mas_equalTo(blueView.mas_trailing).offset(10);
    }];

}
  • 更新约束
-(void)update_masonry_layout{
    _blueView.hidden = YES;
//    [_yellowView mas_remakeConstraints:^(MASConstraintMaker *make) {
//        make.top.width.height.equalTo(self.redView);
//        make.leading.mas_equalTo(self.redView.mas_trailing).offset(10);
//    }];
    //mas_updateConstraints 所做的只是在原有约束的基础上添加约束,如果原来的约束中存在对应的约束就覆盖原约束
    //如果原来的约束不存在对应的约束,并且有约束与新的约束相冲突,就需要先删除原约束
    [self.leftCons uninstall];
    [_yellowView mas_updateConstraints:^(MASConstraintMaker *make) {
        make.leading.mas_equalTo(self.redView.mas_trailing).offset(10);
    }];
}
03-23 15:05