iOS自动布局的学习
Autolayout:
最重要的两个概念:
约束:对控件位置和大小的限定条件参照:对控件设置的约束是相对于哪一个视图而言的
自动布局的核心计算公式:
obj1.property1 =(obj2.property2 * multiplier)+ constant value
解释:obj1的property1属性等于obj2的property2属性乘以multiplier(系数)再加constant(常量);
约束的优先级:
约束的priority属性表示约束的优先级,取值区间为[0,1000],默认为1000。priority值越大,表示优先级越高,会优先执行。优先级低的约束只有在优先级较高的约束失效后才会执行。
警告和错误:
在使用storyboard和xib设置约束时,约束有可能会变成黄色或者红色。当发生这样的情况时,就说明设置的约束有问题。
- 如果约束是黄色的,这只是一个警告,代表控件的frame和设置的约束不相符,更新frame或者更新约束就可以解决。
- 如果约束是红色的,这就代表错误,约束设置不完全或者某两个约束有冲突,只有约束设置完整并且没有冲突,红色错误提示才会消失。
添加约束的3条规则:
- 对于两个同层级View之间的约束关系,应该添加到它们的父View之上。

对于两个不同层级View之间的约束关系,应该添加到它们最近的共同父View上。
不同层级的View- 对于有层次关系的两个view之间的约束关系,添加到层次较高的父view上

代码实现Autolayout:
代码实现Autolayout需要注意:
- 必须先禁止autoresizing功能,设置View的下面属性为
NO:
view.translatesAutoresizingMaskIntoConstraints = NO; - 添加约束之前,一定要保证相关控件都已经添加到各自的父控件上了
- 不用再给View设置frame
利用NSLayoutConstraint类创建具体的约束对象
添加约束到相应的View上:
- (void)addConstraint:(NSLayoutConstraint *)constraint;
- (void)addConstraints:(NSArray *)constraints;
NSLayoutConstraint:
一个NSLayoutConstraint对象就代表一个约束,可以通过修改NSLayoutConstraint对象的属性来修改约束。
创建约束对象常用的方法:
/**
* 添加一个约束,其实就是根据公式来计算约束
* obj1.property1 =(obj2.property2 * multiplier)+ constant value
* @param view1 需要添加约束的View
* @param attr1 需要添加的约束(左边、右边、长宽还是。。。)
* @param relation 约束关系(大于、等于还是小于)
* @param view2 参照View(约束是相对于哪个View而言)
* @param attr2 参照View的哪一个参数(左边、右边、长宽还是。。。)
* @param multiplier 系数
* @param c 常量值
*
* @return 返回一个创建好的约束
*/ + (instancetype)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(nullable id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c;
示例:
UIView *blueView = [[UIView alloc] init];
blueView.backgroundColor = [UIColor blueColor];
[self.view addSubview:blueView]; //关闭Autoresizing
blueView.translatesAutoresizingMaskIntoConstraints = NO; //创建左边约束
NSLayoutConstraint *leftLc = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1.0 constant:];
[self.view addConstraint:leftLc]; //创建右边约束
NSLayoutConstraint *rightLc = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:1.0 constant:-];
[self.view addConstraint:rightLc];
//(这里需要注意一下,blueview的右边界相对于self.view右边的界位置是负数,同理底部(bottom)也是负数)
//创建底部约束
NSLayoutConstraint *bottomLc = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.0 constant:-];
[self.view addConstraint:bottomLc]; //创建高度约束
NSLayoutConstraint *heightLc = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0.0 constant:];
[blueView addConstraint: heightLc];
//这里需要注意一下,NSLayoutAttributeHeight是没有参照视图的。因此toItem为nil mutiplier为0。
效果图:


使用VFL语句添加约束:
使用VFL来创建约束数组:
/**
* 使用VFL语句来创建约束数组
*
* @param format VFL语句
* @param opts 约束类型
* @param metrics VFL语句中用到的具体数值
* @param views VFL语句中用到的控件
*
* @return 返回创建好的约束数组
*/
+ (NSArray<__kindof NSLayoutConstraint *> *)constraintsWithVisualFormat:(NSString *)format options:(NSLayoutFormatOptions)opts metrics:(nullable NSDictionary<NSString *,id> *)metrics views:(NSDictionary<NSString *, id> *)views;
VFL语句示例:
H:[cancelButton()]--[acceptButton()]
canelButton宽72,acceptButton宽50,它们之间间距12 H:[wideView(>=@)]
wideView宽度大于等于60point,该约束条件优先级为700(优先级最大值为1000,优先级越高的约束越先被满足) V:[redBox][yellowBox(==redBox)]
竖直方向上,先有一个redBox,其下方紧接一个高度等于redBox高度的yellowBox H:|--[Find]-[FindNext]-[FindField(>=)]-|
水平方向上,Find距离父view左边缘默认间隔宽度,之后是FindNext距离Find间隔默认宽度;再之后是宽度不小于20的FindField,它和FindNext以及父view右边缘的间距都是默认宽度。(竖线“|” 表示superview的边缘)
VFL代码示例:
// 创建蓝色View
UIView *blueView = [[UIView alloc] init];
blueView.backgroundColor = [UIColor blueColor];
blueView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:blueView]; // 创建红色View
UIView *redView = [[UIView alloc] init];
redView.backgroundColor = [UIColor redColor];
redView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:redView]; // VFL创建约束
// 水平方向
NSString *VFL_H = @"H:|-space-[blueView]-space-[redView(==blueView)]-space-|";
NSDictionary *metrics = @{
@"space" : @,
};
// NSDictionary *views = @{
// @"blueView" : blueView,
// @"redView" : redView
// };
NSDictionary *views = NSDictionaryOfVariableBindings(blueView,redView); NSArray *arrayH = [NSLayoutConstraint constraintsWithVisualFormat:VFL_H options:NSLayoutFormatAlignAllTop metrics:metrics views:views];
[self.view addConstraints:arrayH]; // 垂直方向
NSString *VFL_V = @"V:[blueView(50)]-space-|";//注意:这里V:的后面紧接着是[blueView(50)]并没有“|”。说明对距顶部的距离未做约束
NSArray *arrayV = [NSLayoutConstraint constraintsWithVisualFormat:VFL_V options:kNilOptions metrics:metrics views:views];
[self.view addConstraints:arrayV]; // 添加红色View的约束
// 添加高度约束
NSLayoutConstraint *redV_height = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeHeight multiplier:1.0 constant:];
[self.view addConstraint:redV_height];
效果图:


Masonry的使用:
Masonry是目前最流行的Autolayout第三方框架,让你可以用简单的代码来编写Autolayout,省去了苹果官方繁复的Autolayout代码,大大提升了开发效率。
mas_equalTo和equalTo:
默认情况下mas_equalTo有自动包装功能,比如自动将20包装为@20。equalTo没有自动包装功能。
如果添加了下面的宏,那么mas_equalTo和equalTo就没有区别:
#define MAS_SHORTHAND_GLOBALS
// 注意:这个宏一定要添加到#import "Masonry.h"前面
mas_width和width:
默认情况下
width是make对象的一个属性,用来添加宽度约束用的,表示对宽度进行约束。mas_width是一个属性值,用来当做equalTo的参数,表示某个控件的宽度属性。
如果添加了下面的宏,mas_width也可以写成width:
#define MAS_SHORTHAND
mas_height、mas_centerX以此类推。
下面用Masonry框架实现一下上面VFL语句的示例,对比一下就会发现有了Masonry框架以后自动布局变得多么容易:
//创建蓝色控件
UIView *blueView = [[UIView alloc] init];
blueView.backgroundColor = [UIColor blueColor];
[self.view addSubview:blueView]; //创建红色控件
UIView *redView = [[UIView alloc] init];
redView.backgroundColor = [UIColor redColor];
[self.view addSubview:redView]; // 添加blueView的约束
[blueView makeConstraints:^(MASConstraintMaker *make) {
make.width.equalTo(redView.width).offset();
make.height.equalTo(redView.height).offset();
make.height.equalTo();
make.left.equalTo(blueView.superview.left).offset();
make.bottom.equalTo(blueView.superview.bottom).offset(-);
make.right.equalTo(redView.left).offset(-);
}]; // 添加redView的约束
[redView makeConstraints:^(MASConstraintMaker *make) {
make.bottom.equalTo(redView.superview.bottom).offset(-);
make.right.equalTo(redView.superview.right).offset(-);
}];
Masonry框架提供了很多示例程序,感兴趣的可以打开上面GitHub的链接下载下来仔细研究,这里就不多写了。
GitHub链接为:https://github.com/SnapKit/Masonry
约束动画:
在执行动画时记得调用以下方法:
//在修改了约束之后,只要执行下面代码,约束就能做出动画效果
[UIView animateWithDuration:0.5 animations:^{
[self.view layoutIfNeeded];
}];
使用Autolayout实现UILabel内容包裹:
- 1、设置UILabel的位置约束
- 2、设置
label.numberOfLines = 0;,使label能够自动换行来计算高度 - 3、代码创建约束时,应设置label的最大宽度
preferredMaxLayoutWidth。
作者:真一
链接:https://www.jianshu.com/p/d52fb0d3ea15
iOS自动布局的学习的更多相关文章
- iOS 自动布局详细介绍
1. 自动布局的理解 iOS自动布局很有用,可以在不同size的屏幕上运行,原先看的头痛,还是习惯用最蠢的[UIScreen mainScreen].bounds.size.width等来布局,后来实 ...
- iOS自动布局——Masonry详解
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由鹅厂新鲜事儿发表于云+社区专栏 作者:oceanlong | 腾讯 移动客户端开发工程师 前言 UI布局是整个前端体系里不可或缺的一环 ...
- iOS开发如何学习前端(2)
iOS开发如何学习前端(2) 上一篇成果如下. 实现的效果如下. 实现了一个横放的<ul>,也既iOS中的UITableView. 实现了当鼠标移动到列表中的某一个<li>,也 ...
- iOS开发如何学习前端(1)
iOS开发如何学习前端(1) 我为何学前端?因为无聊. 概念 前端大概三大块. HTML CSS JavaScript 基本上每个概念在iOS中都有对应的.HTML请想象成只能拉Autolayout或 ...
- 移动开发iOS&Android对比学习--异步处理
在移动开发里很多时候需要用到异步处理.Android的主线程如果等待超过一定时间的时候直接出现ANR(对不熟悉Android的朋友这里需要解释一下什么叫ANR.ANR就是Application Not ...
- 关于iOS开发的学习
关于iOS开发的学习,打个比方就像把汽车分解: 最底层的原料有塑料,钢铁 再用这些底层的东西造出来发动机,座椅 最后再加上写螺丝,胶水等,把汽车就拼起来了 iOS基本都是英文的资料, ...
- iOS自动布局学习(UIView+AutoLayout)
自动布局虽然在iOS6的时候已经推出,不过由于各个原因并没有被开发组广泛使用.一方面是大家的app支持版本都是低于iOS6的,另一方面来说是Xcode支持木有现在这么好.以前由于iPhone设备相对固 ...
- 学会爱上iOS自动布局(Auto Layout) - 剑尖
本文翻译自Yari Dareglia的LEARN TO LOVE AUTO LAYOUT文章先生们,女士们,让我们以正确的心态开始本教程吧:自动布局就是简单!我花了一段时间来掌握自动布局是如何工作的, ...
- iOS 自动布局框架 – Masonry 详解
目前iOS开发中大多数页面都已经开始使用Interface Builder的方式进行UI开发了,但是在一些变化比较复杂的页面,还是需要通过代码来进行UI开发的.而且有很多比较老的项目,本身就还在采用纯 ...
随机推荐
- 通过expdp和impdp将Oracle11g数据导入到Oracle10g中
1 导出过程 1.1 查看目录: select * from dba_directories; 1.2 将目录的操作权限赋值给指定的用户(不执行次步骤可能会出现权限问题): grant read,wr ...
- 【BZOJ3514】Codechef MARCH14 GERALD07加强版 LCT+主席树
题解: 还是比较简单的 首先我们的思路是 确定起点 然后之后贪心的选择边(也就是越靠前越希望选) 我们发现我们只需要将起点从后向前枚举 然后用lct维护连通性 因为强制在线,所以用主席树记录状态就可以 ...
- WPF中datagrid不显示滚动条问题
WPF中DataGrid是自带滚动条的,当内容显示不下时可以使用滚动条显示.但是,开发中遇到了DataGrid一直不显示滚动条.之前也曾遇到过同类问题,再次经过查找,发现是StackPanel的原因, ...
- 无法删除另一个分区的windows文件夹
转自:http://zhidao.baidu.com/link?url=77mJiLzVTdr9LzW4R6UYHZ8OJovvXsH8HQb0hyUKL4RKv2J3bItFJgJx-xqAEGOj ...
- JMeter性能测试,验证请求数据的准确性(wc命令)
wc: 该命令统计给定文件中的字节数.字数.行数.如果没有给出文件名,则从标准输入读取. wc同时也给出所有指定文件的总统计数.字是由空格字符区分开的最大字符串. - c 统计字节数. - l 统计行 ...
- 移动端1px问题
.component-confirm__buttons { border-top: 1px solid #eceef0; box-shadow: 0 1px 1px #fff; } 造成边框变粗的原因 ...
- Codeforces 452E Three strings 字符串 SAM
原文链接https://www.cnblogs.com/zhouzhendong/p/CF542E.html 题目传送门 - CF452E 题意 给定三个字符串 $s1,s2,s3$ ,对于所有 $L ...
- 记录一次惊心动魄的sql去重
)) )) url 为判重依据,保留最大id其他的数据状态改为删除状态. concat()函数,为字符串拼接函数 从外到内分析sql 第一层四个条件界定,第一个是source渠道,第二个是未删除状态, ...
- IISExpress运行网站时,Service Fabric报Could not load file or assembly 'Microsoft.ServiceFabric.Data' or one of its dependencies. An attempt was made to load a program with an incorrect format.
打开VS TOOLS > OPTIONS > Projects and Solutions > WEB PROJECTS,选中 "Use the 64 bit vers ...
- Binder原理
--摘自<android插件化开发指南> 1.Binder分为Client和Server两个进程: client和server是相对的.谁发消息,谁就是client:谁接收消息,谁就是se ...
