自動佈局相關

1.實現自動佈局的幾種途徑:1.原生api,VFL、storyboard、第三方masonryapi

2.原生api數組

/**
 系統默認添加約束的方法,它是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
//#pragma clang diagnostic push
//#pragma clang diagnostic ignored "-Warc-"
//#pragma clang diagnostic pop

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

2.vflide

/**
 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];
    
}

3.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);
    }];
    
}

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

4.更新約束的代碼示例code

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    //blueview 被移除後,yellowLeftCons就不成立了,yellowLeftCons_1生效
//    [_blueView removeFromSuperview];

    [self update_masonry_layout];
    
    [UIView animateWithDuration:1
                     animations:^{
                         [self.view layoutIfNeeded];
                     }];
    
    [self update_masonry_layout];
}
相關文章
相關標籤/搜索