利用代码添加autolayout约束

Posted AntonyGu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了利用代码添加autolayout约束相关的知识,希望对你有一定的参考价值。

1.概述

  • 通常我们通过storyboard能够完成的,代码也能够完成,所以这里介绍下代码实现约束的添加,通常我们不这么干(在不使用第三方框架的情况下,使用系统自带的类添加约束特别繁琐),所以这里仅仅简单介绍下代码实现原理

2.实现效果

  • 实现效果 
    技术分享
  • 纯OC代码 
    • 在storyboard中的一条约束在代码中的体现就是一个约束对象,所以添加在storyboard上添加一条约束,相当于创建了一个约束对象并将该约束对象添加到对应的视图上
    • 第一步:创建子控件视图
    • 第二步:禁用子控件的autoresizing属性
    • 第三步:创建约束对象
    • 第四步:添加约束对象
- (void)viewDidLoad {
    [super viewDidLoad];
    // 1.创建一个子视图,添加到父视图上面
    UIView *redView = [[UIView alloc] init];
    redView.backgroundColor = [UIColor redColor];
    [self.view addSubview:redView];
#warning 注意点: 如果通过代码来设置Autolayout约束, 那么必须先禁用Autoresizing
    // 2.禁用autoresizing
    // 2.1给需要设置约束的视图禁用autoresizing,禁用父视图autoresizing对子控件无效
    //self.view.translatesAutoresizingMaskIntoConstraints = NO;//错误写法
    redView.translatesAutoresizingMaskIntoConstraints = NO;

    // 3.添加约束
    // 3.1红色(红色距离顶部和左边以及右边的边距固定为20,高度固定为50)
    // 3.1.1顶部(基于父控件)
    /*
     constraintWithItem:需要设置约束的view
     attribute:需要设置约束的位置
     relatedBy:约束的条件
     toItem:约束依赖目标
     attribute:依赖目标约束位置
     multiplier:配置系数
     constant:额外需要添加的长度
     */
     /*
     计算公式:redView.attribute = self.view.attribute * multiplier + constant;
     其中:=符号取决于relatedBy:参数
     typedef NS_ENUM(NSInteger, NSLayoutRelation) {
     NSLayoutRelationLessThanOrEqual = -1,   小于等于
     NSLayoutRelationEqual = 0,              等于
     NSLayoutRelationGreaterThanOrEqual = 1, 大于等于
     };
     */
    // 3.1.1.1创建约束对象
    NSLayoutConstraint *redTopCos = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:20];
    // 3.1.1.2判断约束条件的层级关系,并添加到对应的视图
    [self.view addConstraint:redTopCos];
    /*
     attribute:传入的是枚举参数
     NSLayoutAttributeLeft = 1,  左边距
     NSLayoutAttributeRight,     右边距
     NSLayoutAttributeTop,       距离顶部边距
     NSLayoutAttributeBottom,    距离底部边距
     NSLayoutAttributeLeading,   左对齐
     NSLayoutAttributeTrailing,  右对齐
     NSLayoutAttributeWidth,     宽度
     NSLayoutAttributeHeight,    高度
     NSLayoutAttributeCenterX,   中点X
     NSLayoutAttributeCenterY,   中点Y
     NSLayoutAttributeBaseline,  文本底线对齐
     */
    // 3.1.2左边约束(基于父控件)
    NSLayoutConstraint *redLeftCos = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1.0 constant:20];
    // 3.1.2.2判断约束条件的层级关系,并添加到对应的视图
    [self.view addConstraint:redLeftCos];

    // 3.1.3右边约束(基于父控件)
    NSLayoutConstraint *redRightCos = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:1.0 constant:-20];
    // 3.1.3.2判断约束条件的层级关系,并添加到对应的视图
    [self.view addConstraint:redRightCos];

    // 3.1.4 高度约束(自身)
    NSLayoutConstraint *redHeightCos = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:0 multiplier:1.0 constant:50];
    // 3.1.3.2判断约束条件的层级关系,并添加到对应的视图
    [redView addConstraint:redHeightCos];
}

  

 

3.VFL语言实现约束的添加

  • 苹果同时为我们提供了VisualFormat语言快速添加约束(使用起来比OC简便一些) 
    技术分享

  • 同样实现上述效果,代码如下:

- (void)viewDidLoad {
    [super viewDidLoad];
    // 1.创建二个子视图,添加到父视图上面
    UIView *redView = [[UIView alloc] init];
    redView.backgroundColor = [UIColor redColor];
    [self.view addSubview:redView];

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


#warning 注意点: 如果通过代码来设置Autolayout约束, 那么必须先禁用Autoresizing
    // 2.禁用autoresizing
    // 2.1给需要设置约束的视图禁用autoresizing,禁用父视图autoresizing对子控件无效
    //self.view.translatesAutoresizingMaskIntoConstraints = NO;//错误写法
    redView.translatesAutoresizingMaskIntoConstraints = NO;
    blueView.translatesAutoresizingMaskIntoConstraints = NO;

    // 3.添加约束
    /*
     VisualFormat: VFL语句
     options: 对齐方式等
     metrics: VFL语句中使用到的一些变量
     views: VFL语句中使用到的一些控件
     */
    // 3.1红色视图
    // 水平方向
    NSArray *hCos = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-20-[redView]-20-|" options:kNilOptions metrics:nil views:NSDictionaryOfVariableBindings(redView)];
    [self.view addConstraints:hCos];

    //竖直方向

    NSArray *vCos = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-20-[redView(==50)]" options:kNilOptions metrics:nil views:NSDictionaryOfVariableBindings(redView)];
    [self.view addConstraints:vCos];


    // 3.2蓝色视图
    // 垂直方向
    NSArray *vBlueCos = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[redView]-20-[blueView(==50)]" options:NSLayoutFormatAlignAllRight metrics:nil views:NSDictionaryOfVariableBindings(redView,blueView)];
    [self.view addConstraints:vBlueCos];
    // 水平方向
    NSLayoutConstraint *hBlueCos = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:redView attribute:NSLayoutAttributeWidth multiplier:0.5 constant:0.0];
    [self.view addConstraint:hBlueCos];
    /*VFL格式说明
     功能        表达式
     水平方向        H:
     垂直方向        V:
     Views        [view]
     SuperView      |
     关系         >=,==,<=
     空间,间隙       -
     优先级        @value
     */
}
NSDictionaryOfVariableBindings(redView,blueView) 也相当于:
@{@"redView": redView , @"blueView": blueView}

[self.contentView addSubview:self.headerImageViewBackgroundView];
    [self.contentView addSubview:self.conversationTitle];
    [self.contentView addSubview:self.messageCreatedTimeLabel];
    [rightContentView addSubview:self.conversationStatusImageView];
    [rightContentView addSubview:self.lastSendMessageStatusView];
    [self.contentView addSubview:rightContentView];
    [self.contentView addSubview:self.messageTypeLabel];
    [self.contentView addSubview:self.messageContentLabel];
    
self.cellSubViews = NSDictionaryOfVariableBindings(_headerImageViewBackgroundView, _conversationTitle,_messageCreatedTimeLabel, _conversationStatusImageView,_lastSendMessageStatusView,rightContentView,_messageContentLabel,_messageTypeLabel);

[self.contentView
     addConstraints:
     [NSLayoutConstraint
      constraintsWithVisualFormat:
      @"H:|-portrait_margin_left-[_headerImageViewBackgroundView(width)]-portrait_margin_right-[_"
      @"conversationTitle]-5-[_messageCreatedTimeLabel(==40)]-12-"
      @"|" options:0 metrics:@{
                               @"portrait_margin_left" :@(portrait_margin_left),
                               @"portrait_margin_right" :@(portrait_margin_right),
                               @"width" :
                                   @([RCIM sharedRCIM].globalConversationPortraitSize.width)
                               } views:self.cellSubViews]];

  

  

 

以上是关于利用代码添加autolayout约束的主要内容,如果未能解决你的问题,请参考以下文章

iOS 在xib或者storyboard中添加AutoLayout后,在代码中修改AutoLayout约束条件

Masonry 代码添加约束

autolayout--约束的优先级

[AutoLayout] 代码添加父视图的比例大小高度

ios-AutoLayout(自动布局代码控制)简单总结

代码加约束VFL语法的详细使用介绍(代替Autolayout进行布局,比Autolayout更简单明了,生动直观)