IOS AutoLayout详解(三)用代码实现(附Demo下载)

原创Blog,转载请注明出处
blog.csdn.net/hello_hwc
欢迎关注我的IOS SDK专栏,这个专栏我会持续进行更新。
IOS SDK详解


前言:

在开发的过程中,有时候创建View没办法通过Storyboard来进行,又需要AutoLayout,这时候用代码创建就派上用场了,这篇文章我会详解用代码实现的两个主要函数,然后讲解一个Demo,最后Demo我会附上下载链接。


用代码实现的函数一

第一个函数通过描述两个view的参考线之间的约束来创建约束,例如有一个label和一个textfield。约束这样描述

label的右边参考线和textfield的右边参考线距离恒定为10

函数

+ (instancetype)constraintWithItem:(id)view1
                         attribute:(NSLayoutAttribute)attr1
                         relatedBy:(NSLayoutRelation)relation
                            toItem:(id)view2
                         attribute:(NSLayoutAttribute)attr2
                        multiplier:(CGFloat)multiplier
                          constant:(CGFloat)c

参数的意义:

参数 意义
view1 左手边的受约束视图
attr1 左手边的受约束视图的参考参数
relation 约束的关系
view2 右手边的受约束视图
multiplier The constant multiplied with the attribute on the right-hand side of the constraint as part of getting the modified attribute.
attr2 The constant added to the multiplied attribute value on the right-hand side of the constraint to yield the final modified attribute.

通常,multiplier的值为1.0。这个不太好翻译,我举个例子就懂了
举个例子
如果,我想要一个View的宽度为另一个View的一半,则

[NSLayoutConstraint
      constraintWithItem:self.view1
               attribute:NSLayoutAttributeWidth
               relatedBy:NSLayoutRelationEqual
                  toItem:self.view2
               attribute:NSLayoutAttributeWidth
              multiplier:0.5
                constant:0.0]];

这里有个计算公式

attribute1 == multiplier × attribute2 + constant
也就是说,在这里
view1.width = view2.width * 0.5 + 0.0

这样,更能够理解上述函数中两个参数的含义了吧。
再举个例子:
我想让一个View距离右上角(30,30)并且保持自己的长宽不变。实现代码

  NSLayoutConstraint * h_c = [NSLayoutConstraint constraintWithItem:self.view
                                                            attribute:NSLayoutAttributeRight
                                                            relatedBy:NSLayoutRelationEqual
                                                               toItem:self.testview
                                                            attribute:NSLayoutAttributeRight
                                                           multiplier:1.0
                                                             constant:30];
    NSLayoutConstraint * v_c = [NSLayoutConstraint constraintWithItem:self.testview
                                                            attribute:NSLayoutAttributeTop
                                                            relatedBy:NSLayoutRelationEqual
                                                               toItem:self.view
                                                            attribute:NSLayoutAttributeTop
                                                           multiplier:1.0
                                                             constant:30];
    NSLayoutConstraint * e_w = [NSLayoutConstraint constraintWithItem:self.testview
                                                            attribute:NSLayoutAttributeWidth
                                                            relatedBy:NSLayoutRelationEqual
                                                               toItem:nil
                                                            attribute:NSLayoutAttributeWidth
                                                           multiplier:1.0 constant:CGRectGetWidth(self.testview.frame)];
    NSLayoutConstraint * e_h = [NSLayoutConstraint constraintWithItem:self.testview
                                                            attribute:NSLayoutAttributeHeight
                                                            relatedBy:NSLayoutRelationEqual
                                                               toItem:nil
                                                            attribute:NSLayoutAttributeHeight
                                                           multiplier:1.0 constant:CGRectGetHeight(self.testview.frame)];
    [self.view addConstraints:@[h_c,v_c,e_h,e_w]];

效果如图
技术分享
技术分享


用代码实现的方法二

方法二使用可视化语言VFL
可视化语言的Apple文档链接如下
https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/VisualFormatLanguage/VisualFormatLanguage.html
利用到的函数为

+ (NSArray *)constraintsWithVisualFormat:(NSString *)format
                                 options:(NSLayoutFormatOptions)opts
                                 metrics:(NSDictionary *)metrics
                                   views:(NSDictionary *)views

参数的的意义

参数 意义
format NSString类型的可视语言描述
opts 描述可视化语言中对象的layout方向
metrics 描述可视化语言中String代表的常量值,字典类型,key为String,value为NSNumber类型
views 描述可视化语言中String代表的对象,字典类型,key为String,value为layout约束的对象

举个例子就懂了,例如,惰性初始化下面一个View,不难看出,这个View我没有指定大小,大小我要用约束来创建

-(UIView *)testview{
    if (!_testview) {
        _testview = [[UIView alloc] init];
        _testview.backgroundColor = [UIColor blueColor];
    }
    return _testview;
}
- (void)viewDidLoad {
    [super viewDidLoad];
    [self.view addSubview:self.testview];
}

然后,我用约束的方式,让View的大小恒定为100*100

   NSArray *c_v = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[testview(==100)]"
                                                                    options:0
                                                                    metrics:nil
                                                                      views:@{@"testview":self.testview}];

    NSArray *c_h = [NSLayoutConstraint constraintsWithVisualFormat:@"H:[testview(==100)]"
                                                                    options:0
                                                                    metrics:nil
                                                                      views:@{@"testview":self.testview}];

    [self.view addConstraints:c_h];
    [self.view addConstraints:c_v];

然后,我再把View约束到距离右上角(30*30)的位置

    NSArray *l_v = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-hdistance-[testview]"
                                                           options:0
                                                           metrics:@{@"hdistance":@(30)}
                                                             views:@{@"testview":self.testview}];

    NSArray *l_h = [NSLayoutConstraint constraintsWithVisualFormat:@"H:[testview]-vdistance-|"
                                                           options:0
                                                           metrics:@{@"vdistance":@(30)}
                                                             views:@{@"testview":self.testview}];

这样,约束后的效果如图
技术分享
技术分享
关于可视化语言的建议

个人而言,比较喜欢用可视化语言的方式来出创建约束。而且也不用刻意去学,一开始使用的时候打开一个链接放在旁边,不会的时候参考下。多用几次,自然就会了。

三 一个Demo

我用上述两种方式实现类似的同一组约束,效果如下
技术分享
技术分享
这里,ImageView的中心始终在view的中心,两个button分别距离ImageView距离为标准距离8,并且分别左右对齐。
用方式一实现的代码

[self.view addSubview:self.imageview];
    [self.imageview setTranslatesAutoresizingMaskIntoConstraints:NO];
    NSLayoutConstraint * hc = [NSLayoutConstraint
                               constraintWithItem:self.view
                               attribute:NSLayoutAttributeCenterX
                               relatedBy:NSLayoutRelationEqual
                               toItem:self.imageview
                               attribute:NSLayoutAttributeCenterX
                               multiplier:1.0
                               constant:0.0];
    NSLayoutConstraint * vc = [NSLayoutConstraint constraintWithItem:self.view
                                                           attribute:NSLayoutAttributeCenterY
                                                           relatedBy:NSLayoutRelationEqual
                                                              toItem:self.imageview
                                                           attribute:NSLayoutAttributeCenterY
                                                          multiplier:1.0
                                                            constant:0.0];
    NSLayoutConstraint * equalW = [NSLayoutConstraint constraintWithItem:self.imageview
                                                               attribute:NSLayoutAttributeWidth
                                                               relatedBy:NSLayoutRelationEqual
                                                                  toItem:nil
                                                               attribute:0
                                                              multiplier:1.0
                                                                constant:CGRectGetWidth(self.imageview.frame)];
    NSLayoutConstraint * equalH = [NSLayoutConstraint constraintWithItem:self.imageview
                                                               attribute:NSLayoutAttributeHeight
                                                               relatedBy:NSLayoutRelationEqual
                                                                  toItem:nil
                                                               attribute:0
                                                              multiplier:1.0
                                                                constant:CGRectGetHeight(self.imageview.frame)];
    [self.view addConstraints:@[hc,vc,equalH,equalW]];
     [self.view addSubview:self.button_1];
     [self.button_1 setTranslatesAutoresizingMaskIntoConstraints:NO];
    NSLayoutConstraint * b1_image_v = [NSLayoutConstraint constraintWithItem:self.imageview
                                                                   attribute:NSLayoutAttributeTop
                                                                   relatedBy:NSLayoutRelationEqual
                                                                      toItem:self.button_1
                                                                   attribute:NSLayoutAttributeBottom
                                                                  multiplier:1.0
                                                                    constant:8.0];
    NSLayoutConstraint * b1_image_h = [NSLayoutConstraint constraintWithItem:self.button_1
                                                                   attribute:NSLayoutAttributeLeft
                                                                   relatedBy:NSLayoutRelationEqual
                                                                      toItem:self.imageview
                                                                   attribute:NSLayoutAttributeLeft
                                                                  multiplier:1.0
                                                                    constant:0.0];

    [self.view addConstraints:@[b1_image_h,b1_image_v]];

    [self.view addSubview:self.button_2];
    [self.button_2 setTranslatesAutoresizingMaskIntoConstraints:NO];
    NSLayoutConstraint * b2_image_v = [NSLayoutConstraint constraintWithItem:self.button_2
                                                                   attribute:NSLayoutAttributeTop
                                                                   relatedBy:NSLayoutRelationEqual
                                                                      toItem:self.imageview
                                                                   attribute: NSLayoutAttributeBottom
                                                                  multiplier:1.0
                                                                    constant:8.0];
    NSLayoutConstraint * b2_image_h = [NSLayoutConstraint constraintWithItem:self.button_2
                                                                   attribute:NSLayoutAttributeRight
                                                                   relatedBy:NSLayoutRelationEqual
                                                                      toItem:self.imageview
                                                                   attribute:NSLayoutAttributeRight
                                                                  multiplier:1.0
                                                                    constant:0.0];

    [self.view addConstraints:@[b2_image_h,b2_image_v]];

用可视化语言VFL的代码

[self.imageview setTranslatesAutoresizingMaskIntoConstraints:NO];
    NSArray * v = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[superview]-(<=1)-[imageview]"
                                                          options:NSLayoutFormatAlignAllCenterX
                                                          metrics:nil
                                                            views:@{@"superview":self.view,@"imageview":self.imageview}];
    NSArray * h = [NSLayoutConstraint constraintsWithVisualFormat:@"H:[superview]-(<=1)-[imageview]"
                                                          options:NSLayoutFormatAlignAllCenterY
                                                          metrics:nil
                                                            views:@{@"superview":self.view,@"imageview":self.imageview}];
    NSArray * ew = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[imageview(==imageviewWidth)]"
                                                           options:0
                                                           metrics:@{@"imageviewWidth":@(CGRectGetHeight(self.imageview.frame))}
                                                             views:@{@"imageview":self.imageview}];
    NSArray * eh = [NSLayoutConstraint constraintsWithVisualFormat:@"H:[imageview(==imageviewHeight)]"
                                                           options:0
                                                           metrics:@{@"imageviewHeight":@(CGRectGetWidth(self.imageview.frame))}
                                                             views:@{@"imageview":self.imageview}];
    [self.view addConstraints:v];
    [self.view addConstraints:h];
    [self.view addConstraints:ew];
    [self.view addConstraints:eh];

    [self.view addSubview:self.button_1];
    [self.button_1 setTranslatesAutoresizingMaskIntoConstraints:NO];
    NSArray * b1_image = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[button1]-[imageview]"
                                                                   options:NSLayoutFormatAlignAllLeft
                                                                   metrics:nil
                                                                     views:@{@"button1":self.button_1,
                                                                             @"imageview":self.imageview}];
    [self.view addConstraints:b1_image];


    [self.view addSubview:self.button_2];
    [self.button_2 setTranslatesAutoresizingMaskIntoConstraints:NO];
    NSArray * b2_image = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[button2]-[imageview]"
                                                                   options:NSLayoutFormatAlignAllRight
                                                                   metrics:nil
                                                                     views:@{@"button2":self.button_2,
                                                                             @"imageview":self.imageview}];
    [self.view addConstraints:b2_image];

最后,附上Demo的下载链接
CSDN下载
前两两篇关于如何在Storyboard上创建AutoLayout的详解
http://blog.csdn.net/hello_hwc/article/details/43982003
http://blog.csdn.net/hello_hwc/article/details/43967561

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。