iOS自动布局进阶用法

本文主要介绍几个我遇到并总结的相对高级的用法(固然啦牛人会以为这也不算什么)。 简单的storyboard中上下左右约束,固定宽高啥的用法在这里就不作赘述了。javascript

autolayout自动布局是iOS6之后出现的,可是在开始的一段时间里你们并不怎么会用,都是一上来先勾掉。以后随着5s,iPhone6的出现屏幕多种多样。用多层if来判断尺寸已经彻底hold不住了才开始学习自动布局。html

在这以前有个叫自动伸缩的autoresizing属性,这个主要用于一个控件和本身父控件之间的关系。只有autolayout才真正能够在任意两个控件中创建关系。java

 若是你不是在董铂然博客园看到本文 请点击查看原文git

关于autoresizing

autoresizing须要注意的是 storyboard中设置的约束和手码中设置的约束是相反的。 storyboard图形页面里点的右边的线和下边的线的意思是“固定”github

而手码中经常使用的autoresizingMasks属性中的枚举都是Flexible可“伸缩”的。 因此假如想要让右边和下边的距离固定,在代码中应该设置左边和上边的可伸缩约束。框架

yellowView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin |UIViewAutoresizingFlexibleTopMargin;

有了autolayout以后这个自动伸缩不多用了 一共七个属性。less

无,宽可伸缩,高可伸缩,左间距可伸缩,右间距可伸缩,上间距可伸缩,下间距可伸缩布局

     UIViewAutoresizingNone                 = 0,学习

     UIViewAutoresizingFlexibleWidth        = 1 << 1,动画

     UIViewAutoresizingFlexibleHeight       = 1 << 4,

     UIViewAutoresizingFlexibleLeftMargin   = 1 << 0,

     UIViewAutoresizingFlexibleRightMargin  = 1 << 2,

     UIViewAutoresizingFlexibleTopMargin    = 1 << 3,

     UIViewAutoresizingFlexibleBottomMargin = 1 << 5

 每一个枚举值都是位移枚举,能够在一行代码中传多个值。

 

关于label的自动识别大小

label想要在界面中显示成这样

意义是下面的控件能够根据上面label的底部进行自动调整。 

这个不是用sizetofit设置的,而是用约束,会在程序运行中数据变了约束当即改变,尺寸也当即改变。

这种设计方法是:

1.设置label的左边和上边的约束,而后再设置下最宽度约束假设是150,把label里面的lines属性设置成0即随意任意多行。 这样里面的文字就会自动换行而且一直显示完,label的背景色也是自动匹配。

2.可是右边还多出了一块。label的右边还有一块蓝色并非牢牢的挨着。这时就要选中那个宽度的约束 再到右边把Relation由本来的equal改为 less than or Equal 。这时候左边的约束显示变了  变成≤了。

运行以后结果是:这里能够清楚的看到label的右边牢牢挨着边了。

3.可是有时候数据可能为空,一旦为空label的大小就被挤没有了,下面的控件也凌乱了。因此为了保证就算数据没有空当也要留着占位,就找给他设置两个高度约束,一个是大于等于一个是小于等于,包裹成一个范围。 这时候要把上面width的小于等于改为equal。

就像这样 这时候运行效果 遇到大量文字和没文字的两种效果是

起到了占位的做用。即便文字没有地方还在。

 

关于Constraints在哪找的问题

左边的图constraints有的在label节点下有的在View节点下,到底是什么缘由决定了constraints在哪一个节点下面?

是看这个约束是否依赖了别的控件,若是就是本身设置固定宽高啥的不关系到别人那就是在本身下面。若是依赖谁设置了间距,那这个约束就会放在本身和依赖的控件的最小公共父控件下。

如图   

 

 

关于手码编写autolayout约束

storyboard界面里面的托拉拽当然方便可是不能批量操做(董铂然原创),假若有相似的30个小控件,storyboard就太麻烦了,手码的话一个循环就完事了

手码建立就是所谓的那七个参数的长的像句子似得方法

以后再在相应的节点下添加约束,有添加一个和添加一组 两种方法。

// 高度约束(添加到yellowView身上)
    NSLayoutConstraint *heightConstraint = [NSLayoutConstraint constraintWithItem:yellowView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0.0 constant:50];
    [yellowView addConstraint:heightConstraint];
    
    // 间距约束(添加到self.view身上)
    CGFloat margin = 20;
    [self.view addConstraints:@[
                                // 左边
                                [NSLayoutConstraint constraintWithItem:yellowView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1.0 constant:margin],
                                
                                // 右边
                                [NSLayoutConstraint constraintWithItem:yellowView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:1.0 constant: - margin],
                                
                                // 底部
                                [NSLayoutConstraint constraintWithItem:yellowView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.0 constant: - margin]
                                ]];
}

  

这里用到了一个核心公式,任何两个控件间的约束均可以经过这个公式算出

obj1.property1 =(obj2.property2 * multiplier)+ constant value

multiplier和constant 就是向量系数和偏移量

还有为了不和系统生成的自动伸缩的约束不冲突 通常加上这句

系统默认这个属性是yes

 

 

关于VFL语言 

Visual Format Language,翻译过来是“可视化格式语言”  是苹果公司为了简化Autolayout的编码而推出的抽象语言
至关于打出象形文字似得,并且要全在字符串里写,遇到错误比较难调,可是相对来讲代码精简了很多。
而后在添加约束的时候就会用到系统提供的另一种方法。
    NSArray *contraints = [NSLayoutConstraint constraintsWithVisualFormat:vfl options:kNilOptions metrics:metrics views:views];

VFL的详细语法 能够在官方文档中 搜 “Visual Format” 就能搜到 

上面的方法中传到的两个参数metrics 和 views 是两个字典。(董铂然原创) 第一个字典metrics是用来告诉系统里面的每个值对应哪一个字母 

第二个字典views是 用来告诉里面的每个控件对应字符串里的什么

若是整个VFL语言里的全部控件你都是用原名写在里面的,那能够用宏代替

括号里能够传多个值逗号隔开

 

关于经常使用的手码约束的第三方框架

有 Masonry 和 UIView+Autolayout

框架地址是:

https://github.com/Masonry/Masonry 

https://github.com/smileyborg/UIView-AutoLayout

 

UIView+Autolayout框架

这个相对于masonry,是个轻量级的框架易于上手,里面一共也就两个文件。也很是好用,都是用auto开头。适用于约束不常常改变的项目

事例用法:

直接设置四周的间隔距离

[self.yellowView autoPinEdgesToSuperviewEdgesWithInsets:UIEdgeInsetsMake(20, 20, 20, 20)]; //直接设置四周的间隔距离

设置三个间隔,而后再添加个高度,

[self.yellowView autoPinEdgesToSuperviewEdgesWithInsets:UIEdgeInsetsMake(20, 20, 20, 20)excludingEdge:ALEdgeTop]; // 让顶部约束无效
    [self.yellowView autoSetDimension:ALDimensionHeight toSize:100]; // 本身再添加个高度约束正好四个

也能够直接设置大小

[self.yellowView autoSetDimensionsToSize:CGSizeMake(200, 200)];

总之还有不少用法,在这不一一介绍了,大概就是这个代码风格。有兴趣的能够去上面说的那个github地址上仔细查看。

 

 

Masonry框架

这个框架是重量级的里面好多文件,难于上手,可是用熟练了的话比上面那个牛X,适合于约束要常常改变的项目。
示例代码:
添加距离四个方向20的间隔约束
[yellowView mas_makeConstraints:^(MASConstraintMaker *make) {
        // make表明yellowView
        // 添加约束
        make.edges.equalTo(self.view).insets(UIEdgeInsetsMake(20, 20, 20, 20));
    }];

下面这个是更新约束,很是方便会自动识别上左下右的属性来更改。

[self.yellowView mas_updateConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self.view.mas_left).offset(100);
        make.top.equalTo(self.view.mas_top).offset(100);
        make.right.equalTo(self.view.mas_right).offset(-100);
        make.bottom.equalTo(self.view.mas_bottom).offset(-100);
    }];

还有一些别的属性用法。

主要是做者设置的属性比较多这张图摘自他的github,有兴趣能够去github仔细看

 

关于想给约束改变添加动画。

由于约束的改变是瞬时操做和frame的概念不同,因此把约束的代码放在动画的block里是无效的
错!
正确作法是,把约束写在外面面,而后在动画的block中包裹 layoutifneed
对!
 若是你不是在董铂然博客园看到本文 请点击查看原文
对了还有一个注意点是:须要依赖父控件的约束要在添加了父控件以后再写。
有什么不一样的见解欢迎评论。本博客全部文章均原创,转载请注明出处
相关文章
相关标签/搜索