【IOS开发基础系列】Autolayout自动布局专题

2023-10-16 11:44:03 浏览数 (3)

1 简介

        bounds是指这个view在它自己坐标系的坐标和大小 而frame指的是这个view在它superview的坐标系的坐标和大小区别主要在坐标系这一块。很明显一个是自己为原点的坐标系,一个是以屏幕为原点的坐标系。

        当谈到自动布局,橙色代表坏的。InterfaceBuilder绘制两个橙色方块:一个是虚线边框,一个是实线边框。虚线方块是根据自动布局显示视图的frame。实线方块是根据你在屏幕上放置的视图的frame。这两个应该吻合的,但是这里并没有。

Note:你可能会奇怪,为什么Xcode不为X轴方向自动增加一个约束。Xcode中的规则是:Xcode只为那些你没有设置任何约束的对象创建自动约束。一旦你增加一个约束,你便是告诉Xcode你接管了这个视图。Xcode将不再增加任何自动约束,并希望你为这个视图增加需要的约束。

2 代码实现自动布局

2.1 使用方法

2.1.1 添加约束的方法

        代码中一般用到的有两个添加约束的方式:

    1. - (void) addConstraint: (NSLayoutConstraint *) constraint    NS_AVAILABLE_IOS (6_0);

    2. - (void) addConstraints: (NSArray *) constraints    NS_AVAILABLE_IOS(6_0);

        在使用自动布局之前要对子视图的布局方式进行调整,用到这个UIView的属性。

- (BOOL) translatesAutoresizingMaskIntoConstraints     NS_AVAILABLE_IOS(6_0); // Default YES

需要将其设置为NO;

2.1.2 关于constraintsWithVisualFormat:函数介绍:

       constraintsWithVisualFormat:参数为NSString型,指定Contsraint的属性,是垂直方向的限定还是水平方向的限定,参数定义一般如下:

    V:|-(>=XXX) :表示垂直方向上相对于SuperView大于、等于、小于某个距离

    若是要定义水平方向,则将V:改成H:即可。

    在接着后面-[]中括号里面对当前的View/控件 的高度/宽度进行设定;

options:字典类型的值;这里的值一般在系统定义的一个enum里面选取;

metrics:nil;一般为nil,参数类型为NSDictionary,从外部传入//衡量标准;

views:就是上面所加入到NSDictionary中的绑定的View;

        在这里要注意的是AddConstraints  和AddConstraint之间的区别,一个添加的参数是NSArray,一个是NSLayoutConstraint;

    使用规则:

        |:表示父视图

        -:表示距离

        V:  :表示垂直

        H:  :表示水平

        >= :表示视图间距、宽度和高度必须大于或等于某个值

        <= :表示视图间距、宽度和高度必须小宇或等于某个值

        == :表示视图间距、宽度或者高度必须等于某个值

        @  :>=、<=、==  限制  最大为  1000

1. |-[view]-|:  视图处在父视图的左右边缘内

2. |-[view]  :   视图处在父视图的左边缘

3. |[view]   :   视图和父视图左边对齐

4. -[view]-  :  设置视图的宽度高度

5. |-30.0-[view]-30.0-|: 表示离父视图 左右间距  30

6. [view(200.0)] :表示视图宽度为200.0

7. |-[view(view1)]-[view1]-| :表示视图宽度一样,并且在父视图左右边缘内

8. V:|-[view(50.0)] :视图高度为 50

9: V:|-(==padding)-[imageView]->=0-[button]-(==padding)-|:表示离父视图的距离为Padding,这两个视图间距必须大于或等于0并且距离底部父视图为padding。

10: [wideView(>=60@700)]  :视图的宽度为至少为60不能超过  700

11: 如果没有声明方向默认为  水平 V:

2.1.3 示例

    下面用简单例子说明一下:

UIView *v1 = [[UIView alloc] initWithFrame: CGRectZero];

v1.translatesAutoresizingMaskIntoConstraints = NO;

v1.backgroundColor = [UIColor redColor];

 [self.viewaddSubview: v1];

UIView *v2 = [[UIView alloc] initWithFrame: CGRectZero];

v2.backgroundColor = [UIColor grayColor];

v2.translatesAutoresizingMaskIntoConstraints = NO;

[self.view addSubview: v2];    //添加两个允许自动布局的子视图

//设置子视图的宽度和父视图的宽度相同

[self.view addConstraint: [NSLayoutConstraint constraintWithItem: v1 attribute: NSLayoutAttributeWidth relatedBy: NSLayoutRelationEqual toItem: self.view

attribute: NSLayoutAttributeWidth multiplier: 1.0 constant:0]]; 

//设置子视图的高度是父视图高度的一半

[self.view addConstraint: [NSLayoutConstraint constraintWithItem: v1 attribute: NSLayoutAttributeHeight relatedBy: NSLayoutRelationEqual toItem: self.view attribute: NSLayoutAttributeHeight multiplier: 0.5 constant: 0]];

//通过addConstraints添加对水平方向上v1的控制--距离父视图左侧距离为0(距离为0的话也可省略)同时将v2的水平方向的宽度和v1设置成相同

[self.view addConstraints: [NSLayoutConstraint constraintsWithVisualFormat: @"H:|-0-[v1][v2(==v1)]-0-|" options: 0 metrics: nil views: views]];

//通过addConstraints添加对垂直方向上v1的控制--距离父视图上侧距离为0(距离为0的话也可省略)同时将v2的垂直方向的高度和v1设置成相同

 [self.viewaddConstraints:[NSLayoutConstraint constraintsWithVisualFormat: @"V:|-0-[v1][v2(==v1)]|"options:0 metrics:nil views:views]];

//最后是垂直布局两个子view

[self.viewaddConstraints:[NSLayoutConstraint constraintsWithVisualFormat: @"V:|-0-[v1]-0-[v2]-0-|"options:0 metrics:nil views:views]];

        这样就可以实现上下两个view,各占一半。旋转屏幕的情况下也会自动处理布局。这样看起来代码多,但是可以适应多种分辨率的屏幕。不排除以后苹果出更大更多分辨率的手机。

2.2 AutoLayout框架介绍(ZXPAutoLayout)

        iOS原生的自动布局(NSLayoutConstraint)非常繁琐, 影响开发进度和可读性也不利于维护, 正所谓工欲善其事必先利其器 , 有一个良好的自动布局框架, 则会让我们事半功倍. 而ZXPAutoLayout则是解决这一问题和诞生 . 采用新颖的链式语法, 扩展性,可读性,维护成本也较低.并致力打造最好用,最简洁,最方便,最轻巧的自动布局。

        以下一个简单示例。ZXPAutoLayout详细教程点此- github地址点此

//设置一个背景为半透明红色的view,上下左右四边都距离superview的距离为10

UIView *bgView = [UIView new];

[self.view addSubview: bgView];

bgView.backgroundColor = [[UIColor redColor] colorWithAlphaComponent: 0.5];

[bgView zxp_addConstraints: ^(ZXPAutoLayoutMaker *layout) {

    //上下左右四边都距离superview的距离为10

    layout.edgeInsets(UIEdgeInsetsMake(10, 10, 10, 10));

    //也可以如下这行代码来设置,但要同时设置top,left,bottom,right.推荐以上写法,比较简洁.

    //layout.topSpace(10).leftSpace(10).bottomSpace(10).rightSpace(10);

}];

//设置一个背景为半透明红色的view,上下左右四边都距离superview的距离为10

UIView *bgView =[UIView new];

[self.viewaddSubview:bgView];

bgView.backgroundColor = [[UIColor redColor] colorWithAlphaComponent: 0.5];

[bgView zxp_addConstraints: ^(ZXPAutoLayoutMaker*layout) {

    //上下左右四边都距离superview的距离为10

    layout.edgeInsets(UIEdgeInsetsMake(10, 10, 10, 10));

    //也可以如下这行代码来设置,但要同时设置top,left,bottom,right.推荐以上写法,比较简洁.

    //layout.topSpace(10).leftSpace(10).bottomSpace(10).rightSpace(10);

}];

3 界面设置实现自动布局

iOS8开发~UI布局(二)storyboard中autolayout和sizeclass的使用详解

http://blog.csdn.net/liangliang103377/article/details/40082255

        用Xcode在Storyboard界面配置自动布局要点:

    1、对于一个视图内同级别的子视图,要配就全部都配置成自动布局;

    2、对于每个视图,无法上下左右四个方向上的设置,一定要设置全;

    3、对于TableView等大型视图控件,默认顶行就行,无须手动考虑导航条与状态栏高度;

        重点参考IM_RAC项目中,IMSingleChatVC的自动布局设置

4 开发问题汇总

4.1 Constraint问题

4.1.1 不能同时设置一个控件横向或纵向的相对间距后,又去设置绝对尺寸,否则会导致控件不能显示,也不会报错!
4.1.2 Constraint可以只使用部分,细节控件可去代码中做
4.1.3 Constraint中设计的布局一定与代码中设计得布局保持一致

        使用Storyboard进行布局设计后,系统运行时会总是以Storyboard中布局来刷新页面,所以代码中设计得布局一定要与Constraint中设计的布局保持一致。不然会导致布局混乱。

4.1.4 在故事板中进行布局设计时,如果有导航栏、Tab栏,必须也要把高度预留出来

iPhone iPad各种控件默认高度

http://blog.csdn.net/chengyakun11/article/details/7565690

5 参考链接

'Unable to create description indescriptionForLayoutAttribute_layoutItem_coefficient. Something is nil'

http://stackoverflow.com/questions/26024906/unable-to-create-description-in-descriptionforlayoutattribute-layoutitem-coeffi

Unable to create description indescriptionForLayoutAttribute添加了系统约束无法在ios7运行

http://bbs.csdn.net/topics/390950336?page=1

Size Classes with Xcode 6:为所有的尺寸准备一个Storyboard

http://www.cocoachina.com/ios/20140926/9766.html

Storyboard自动布局

http://demo.netfoucs.com/hmt20130412/article/details/24653659

开始iOS7中自动布局教程(一)

http://www.cocoachina.com/industry/20131203/7462.html

【iOS开发】多屏尺的自动适配AutoLayout(纯代码方式)

http://blog.sina.com.cn/s/blog_693de6100102v4sl.html

iOS开发:iPhone6、6 plus适配

http://jingyan.baidu.com/article/8cdccae97a5c2b315413cda9.html

开始iOS 7中自动布局教程(一)

http://www.cocoachina.com/industry/20131203/7462.html

(翻译)开始iOS 7中自动布局教程(二)

http://www.cnblogs.com/zer0Black/p/3977288.html

http://blog.csdn.net/dizzthxl/article/details/9009537

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

http://blog.sina.com.cn/s/blog_7c336a830102vaht.html

IOS学习之路(代码实现自动布局)

http://www.tuicool.com/articles/B3iiU3J

iOS开发笔记--使用AutoLayout中的VFL(Visualformat language)--代码实现自动布局

http://blog.csdn.net/hopedark/article/details/41844071

使用了Autolayout和约束后,无法用代码修改View的位置,怎么处理?(7楼)

http://www.cocoachina.com/bbs/read.php?tid-256011-page-1.html

在代码中更新AutoLayout约束

http://blog.sina.com.cn/s/blog_6291e42d0102uzav.html

关于autolayout需要频繁变更的讨论

http://segmentfault.com/q/1010000002420050

实时显示iOS编写UI代码效果

http://blog.csdn.net/zhang_red/article/details/45503683

0 人点赞