代码添加约束如何实现
2017-03-11 01:00
183 查看
代码添加约束
目标
理解用纯代码设置自动布局约束的方法理解为什么在使用自动布局开发时,千万不要修改 frame?
理解 VFL 语法
提示:自动布局方法的参数很多,第一次接触难免会有抵触情绪
但是参数的含义很容易懂!
为什么要学习纯代码的自动布局?
自己开发第三方框架会使用
其他第三方框架中会使用,遇到时能够看得懂
知识点
理解用NSLayoutConstraint类创建具体的约束对象的步骤与参数
理解用
VFL添加自动布局的方法
理解
VFL语法
用代码实现 Autolayout
的步骤
禁用 autoresizing
利用以下方法添加约束
/// 添加一个约束
- (void)addConstraint:(NSLayoutConstraint *)constraint;
/// 添加多个约束 VFL 专用
- (void)addConstraints:(NSArray *)constraints;
/// 创建一个约束
[NSLayoutConstraint constraintWithItem:...
/// 利用 VFL 创建多个约束
[NSLayoutConstraint constraintsWithVisualFormat:...
注意:约束添加的位置
如果约束没有参照任何其他视图,则约束添加在自身(苹果建议),或者父视图上(常见)如果约束有参照父视图,则约束添加到父视图上
如果约束有参照兄弟视图,则约束添加到它们最近的父视图上
对于两个不同层级view之间的约束关系,添加到他们最近的共同父view上
案例 1 —— addConstraint
要求
定义一个视图 200 * 50在任何设备上都摆放在屏幕的中心点
代码实现
代码准备- (void)viewDidLoad { [super viewDidLoad]; [self autoLayout1]; } /** * 案例 1 * * 定义一个视图 200 * 50 * 在任何设备上都摆放在屏幕的中心点 */ - (void)autoLayout1 { UIView *v = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)]; v.backgroundColor = [UIColor redColor]; [self.view addSubview:v]; }
添加水平约束
// 定义约束,并且添加到 self.view 上 // 1. 水平约束 NSLayoutConstraint *horCons = [NSLayoutConstraint constraintWithItem:v // 添加约束的视图 attribute:NSLayoutAttributeCenterX // 要设置约束的属性 centerX relatedBy:NSLayoutRelationEqual // 相等 toItem:self.view // 参照的视图 attribute:NSLayoutAttributeCenterX // 参照视图的属性 multiplier:1.0 // 乘积 constant:0]; // 约束值,如果和参照属性想等,此处传入 0 // 将水平约束添加到视图的父视图上 [self.view addConstraint:horCons];
添加垂直约束,由于一般约束设置完成后,直接添加给 view,所以不会定义临时变量
// 2. 垂直约束 [self.view addConstraint:[NSLayoutConstraint constraintWithItem:v attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0]];
运行测试,会报以下错误
Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) ...
在使用代码开始时,默认是使用
AutoResizing的
而 AutoResizing 和 AutoLayout 不能共存
因此用代码开发的时候,一定要把视图的
translatesAutoresizingMaskIntoConstraints设置为
NO
取消
autoresizing
// 0. 取消 autoresizing v.translatesAutoresizingMaskIntoConstraints = NO;
运行测试,视图不见了,因为只要使用自动布局,
frame的计算工作会被自动布局系统完全接管
提示:在使用自动布局开发时,千万不要修改 frame
添加宽度约束
// 3. 设置宽度 [self.view addConstraint:[NSLayoutConstraint constraintWithItem:v // 添加约束的视图 attribute:NSLayoutAttributeWidth // 宽度 relatedBy:NSLayoutRelationEqual // 想等 toItem:nil // 没有参照视图,传入 nil attribute:NSLayoutAttributeNotAnAttribute // 当 toItem == nil 时,传入 NSLayoutAttributeNotAnAttribute multiplier:1.0 // 乘积 constant:200]]; // 约束值,如果没有参照对象,直接传入宽度数值
添加高度约束
// 4. 设置高度 [self.view addConstraint:[NSLayoutConstraint constraintWithItem:v attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:50]];
VFL 介绍
为了简化程序员开发时编写大量的约束,苹果推出了 VFL —— 可视化格式语言VFL 语法
H: 水平方向
V: 垂直方向
| 边界
[视图名称]
(常数值)
=
>=
<=关系
-距离
VFL 示例
H:|-0-[button]-0-|
按钮 距离
左右两边为 0
V:|-0-[button]-0-|
b961
按钮 距离
上下两边为 0
H:|-20-[button(50)]
按钮 距离
左边 20
按钮宽度 50
V:[button(40)]-20-|
按钮 距离
底边 20
按钮高度 40
VFL 没有提供居中对齐的方式
案例 2 —— constraintsWithVisualFormat(VFL)
要求
定义两个 UITextField 水平距离左右两边 20 点第一个 UITextField 垂直距离顶边 20 点
第二个 UITextField 垂直距离第一个 20 点
代码准备
- (void)viewDidLoad { [super viewDidLoad]; [self autoLayout2]; } /** * 案例 2 * * 定义两个 UITextField 水平距离左右两边 20 点 * 第一个 UITextField 垂直距离顶边 20 点 * 第二个 UITextField 垂直距离第一个 20 点 */ - (void)autoLayout2 { // 1. 创建控件 UITextField *tf1 = [[UITextField alloc] initWithFrame:CGRectMake(20, 20, 200, 40)]; tf1.borderStyle = UITextBorderStyleRoundedRect; [self.view addSubview:tf1]; UITextField *tf2 = [[UITextField alloc] initWithFrame:CGRectMake(20, 80, 200, 40)]; tf2.borderStyle = UITextBorderStyleRoundedRect; [self.view addSubview:tf2]; }
取消 autoresizing
// 2. 取消 autoresizing for (UIView *v in self.view.subviews) { v.translatesAutoresizingMaskIntoConstraints = NO; }
一旦取消了
autoresizing,控件的 frame 就会失效
添加 第一个文本框的宽度 约束
// 3. 添加约束 // 3.0 生成控件映射字典,视图影射字典,告诉系统 VFL 中的 [控件] 对应哪个控件 NSDictionary *viewDict = @{@"tf1": tf1, @"tf2": tf2}; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-20-[tf1]-20-|" // VFL options:0 // 通常传入 0 metrics:nil // 通常传入 nil views:viewDict]]; // 视图影射字典,告诉系统 VFL 中的 [控件] 对应哪个控件
添加 第二个文本框的宽度 约束
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-20-[tf2]-20-|" // VFL options:0 // 通常传入 0 metrics:nil // 通常传入 nil views:viewDict]]; // 视图影射字典,告诉系统 VFL 中的 [控件] 对应哪个控件
添加高度约束
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-20-[tf1(28)]-20-[tf2(==tf1)]" // VFL options:0 // 通常传入 0 metrics:nil // 通常传入 nil views:viewDict]]; // 视图影射字典,告诉系统 VFL 中的 [控件] 对应哪个控件
metrics 字典使用
// 设置 VFL 中的数值字典 NSDictionary *metrics = @{@"space": @(100)}; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-20-[tf1(28)]-(==space)-[tf2(==tf1)]" // VFL options:0 // 通常传入 0 metrics:metrics // 设置 VFL 中的数值字典 views:viewDict]]; // 视图影射字典,告诉系统 VFL 中的 [控件] 对应哪个控件
VFL 文档地址
iOS -> Cocoa Touch Layer -> UIKit -> Guide -> AutoLayoutGuid
Part V: Appendix Visual Format Language
相关文章推荐
- NSLayoutConstraint 使用代码实现约束的添加和删除
- 通过代码实现约束 NSLayoutConstraint + VFL添加约束
- 如何实现在已有代码之后添加逻辑之继承,组合(静态代理)实现方法
- 章鱼哥—VB.NET 如何实现代码自动生成控件 添加绑定事件
- 在xib和story board上实现代码自动布局(解决添加约束时,大于等于小于等于繁琐的问题,以及占位view的问题)
- .net c# gif动画如何添加图片水印实现思路及代码学习
- .net c# gif动画如何添加图片水印实现思路及代码
- .net c# gif动画如何添加图片水印实现思路及代码
- 某表,多字段关联,多种约束,如何做(触发器实现代码)?
- 如何实现在已有代码之后添加逻辑之java动态代理
- html4和html5区别之如何在一个input上添加焦点实现代码
- 如何在C#代码中实现在Sqlserver2000中添加用户?以及附加数据库?
- 如何用Shell实现程序组快捷方式的添加
- 在C#代码中实现在Sqlserver2000中添加用户以及附加数据库
- 《Asp.Net Forums2.0深入分析》之 Asp.Net Forums是如何实现代码分离和换皮肤的
- javascript代码如何实现打印框架里面的某个网页
- 如何实现服务器端下页面动态添加JavaScript脚本
- 如何实现服务器端下页面动态添加JavaScript脚本
- 【导读】本文介绍如何利用带进度条的ASP无组件实现断点续传下载,给出详细代码
- 《Asp.Net Forums2.0深入分析》之 Asp.Net Forums是如何实现代码分离和换皮肤