【转】IOS AutoLayout详解(三)用代码实现(附Demo下载)
转载自:blog.csdn.net/hello_hwc
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:];
- NSLayoutConstraint * v_c = [NSLayoutConstraint constraintWithItem:self.testview
- attribute:NSLayoutAttributeTop
- relatedBy:NSLayoutRelationEqual
- toItem:self.view
- attribute:NSLayoutAttributeTop
- multiplier:1.0
- constant:];
- 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:
- metrics:nil
- views:@{@"testview":self.testview}];
- NSArray *c_h = [NSLayoutConstraint constraintsWithVisualFormat:@"H:[testview(==100)]"
- options:
- 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:
- metrics:@{@"hdistance":@()}
- views:@{@"testview":self.testview}];
- NSArray *l_h = [NSLayoutConstraint constraintsWithVisualFormat:@"H:[testview]-vdistance-|"
- options:
- metrics:@{@"vdistance":@()}
- 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:
- multiplier:1.0
- constant:CGRectGetWidth(self.imageview.frame)];
- NSLayoutConstraint * equalH = [NSLayoutConstraint constraintWithItem:self.imageview
- attribute:NSLayoutAttributeHeight
- relatedBy:NSLayoutRelationEqual
- toItem:nil
- attribute:
- 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:
- metrics:@{@"imageviewWidth":@(CGRectGetHeight(self.imageview.frame))}
- views:@{@"imageview":self.imageview}];
- NSArray * eh = [NSLayoutConstraint constraintsWithVisualFormat:@"H:[imageview(==imageviewHeight)]"
- options:
- 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
【转】IOS AutoLayout详解(三)用代码实现(附Demo下载)的更多相关文章
- IOS SDK详解
来源:http://blog.csdn.net/column/details/huangwenchen-ios-sdk.html?page=1#42803301 博客专栏>移动开发专栏>I ...
- iOS路由详解
本文如题,路由详解,注定是一篇详细解释iOS路由原理及使用的文章,由于此时正在外地出差,无法详细一一写出,只能不定时的补充. 一.什么是iOS路由 路由一词来源于路由器,可以实现层级之间消息转发的功能 ...
- Android 之窗口小部件详解(三) 部分转载
原文地址:http://blog.csdn.net/iefreer/article/details/4626274. (一) 应用程序窗口小部件App Widgets 应用程序窗口小部件(Widget ...
- SQL Server 表的管理_关于事务的处理的详解(案例代码)
SQL Server 表的管理_关于事务的处理的详解(案例代码) 一.SQL 事务 1.1SQL 事务 ●事务是在数据库上按照一定的逻辑顺序执行的任务序列,既可以由用户手动执行,也可以由某种数据库程序 ...
- WebSocket安卓客户端实现详解(三)–服务端主动通知
WebSocket安卓客户端实现详解(三)–服务端主动通知 本篇依旧是接着上一篇继续扩展,还没看过之前博客的小伙伴,这里附上前几篇地址 WebSocket安卓客户端实现详解(一)–连接建立与重连 We ...
- python设计模式之装饰器详解(三)
python的装饰器使用是python语言一个非常重要的部分,装饰器是程序设计模式中装饰模式的具体化,python提供了特殊的语法糖可以非常方便的实现装饰模式. 系列文章 python设计模式之单例模 ...
- http500:服务器内部错误案例详解(服务器代码语法错误或者逻辑错误)
http500:服务器内部错误案例详解(服务器代码语法错误或者逻辑错误) 一.总结 服务器内部错误可能是服务器中代码运行的时候的语法错误或者逻辑错误 二.http500:服务器内部错误案例详解 只是一 ...
- .NET DLL 保护措施详解(三)最终效果
针对.NET DLL 保护措施详解所述思路完成最终的实现,以下为程序包下载地址 下载 注意: 运行环境为.net4.0,需要安装VS2015 C++可发行组件包vc_redist.x86.exe.然后 ...
- SQL Server 表的管理_关于数据增删查改的操作的详解(案例代码)
SQL Server 表的管理_关于数据增删查改的操作的详解(案例代码)-DML 1.SQL INSERT INTO 语句(在表中插入) INSERT INTO 语句用于向表中插入新记录. SQL I ...
随机推荐
- vs2015
1.关闭诊断工具 vs2015在程序启动之后,自带了内存和cpu使用情况查看的诊断工具. 不喜欢这个,直接点击诊断工具右上角的关闭按钮 2.解决方案资源管理器 程序启动之后,解决方案资源管理器,被收缩 ...
- http://www.cnbc.com/2016/07/12/tensions-in-south-china-sea-to-persist-even-after-court-ruling.html
http://www.cnbc.com/2016/07/12/tensions-in-south-china-sea-to-persist-even-after-court-ruling.html T ...
- 连接池 BoneCPDataSource
一篇连接池不错的文章 http://blog.csdn.net/vincent_czz/article/details/7646392
- MySQL表设计基础
MySQL表设计关于blog数据库中建立所有表的sql语句<一.>sql语句中 约束概念constraint concept1.1 实体完整性entity integrity(主键--唯一 ...
- Java GC专家系列1:理解Java垃圾回收
了解Java的垃圾回收(GC)原理能给我们带来什么好处?对于软件工程师来说,满足技术好奇心可算是一个,但重要的是理解GC能帮忙我们更好的编写Java应用程序. 上面是我个人的主观的看法,但我相信熟练掌 ...
- kafka集群扩容以及数据迁移
一 kafka集群扩容比较简单,机器配置一样的前提下只需要把配置文件里的brokerid改一个新的启动起来就可以.比较需要注意的是如果公司内网dns更改的不是很及时的话,需要给原有的旧机器加上新服务器 ...
- CSS3新特性(阴影、动画、渐变、变形、伪元素等)
CSS3与页面布局学习总结(六)--CSS3新特性(阴影.动画.渐变.变形.伪元素等) 目录 一.阴影 1.1.文字阴影 1.2.盒子阴影 二.背景 2.1.背景图像尺寸 2.2.背景图像显示的原 ...
- c# 发送邮件、附件 分类: C# 2014-12-17 16:41 201人阅读 评论(0) 收藏
WinForm窗体代码如下: <span style="font-size:14px;">using System; using System.Collections. ...
- WinForm中关于控件焦点的问题
方法一: 在打开一个窗体时,我们往往需要设置焦点让光标出现在我们希望它出现的位置上. 这时我们可以在窗体的Activated事件中设置焦点 例如我们希望光标在打开窗体的时候出现在textBox1上,我 ...
- visual studio 2015 企业版 序列号及官方下载地址
VisualStudio 2015 正式版已经可以通过官方下载了. Visual Studio 是一套基于组件的软件开发工具和其他技术,可用于构建功能强大.性能出众的应用程序.Visual Studi ...