iOS自动布局学习(UIView+AutoLayout)
自动布局虽然在iOS6的时候已经推出,不过由于各个原因并没有被开发组广泛使用。一方面是大家的app支持版本都是低于iOS6的,另一方面来说是Xcode支持木有现在这么好。以前由于iPhone设备相对固定,所以在纯代码,纯坐标的布局下很流行,不过现在随着iPhone6发布,如果还要写一大堆乱七八糟的绝对坐标去适配,那工作量和维护成本是很大的。
下面的一些基础直接拿小伙伴分享整理的吧,之后向大家推荐一个开源的库,对AutoLayout进行了封装,用起来很简单也高效。
1.AutoLayout是什么?
使用一句Apple的官方定义的话
- 基于约束 - 和以往定义frame的位置和尺寸不同,AutoLayout的位置确定是以所谓相对位置的约束来定义的,比如x坐标为superView的中心,y坐标为屏幕底部上方10像素等
- 描述性 - 约束的定义和各个view的关系使用接近自然语言或者可视化语言(VFL)的方法来进行描述
- 布局系统 - 即字面意思,用来负责界面的各个元素的位置。
总而言之,AutoLayout为开发者提供了一种不同于传统对于UI元素位置指定的布局方法。以前,不论是在IB里拖放,还是在代码中写,每个UIView都会有自己的frame属性,来定义其在当前视图中的位置和尺寸。使用AutoLayout的话,就变为了使用约束条件来定义view的位置和尺寸。这样的最大好处是一举解决了不同分辨率和屏幕尺寸下view的适配问题,另外也简化了旋转时view的位置的定义,原来在底部之上10像素居中的view,不论在旋转屏幕或是更换设备(iPad或者iPhone5或者以后可能出现的mini iPad)的时候,始终还在底部之上10像素居中的位置,不会发生变化。总结
1.1AutoLayout和Autoresizing Mask的区别
在iOS6之前,关于屏幕旋转的适配和iPhone,iPad屏幕的自动适配,基本都是由Autoresizing Mask来完成的。但是随着大家对iOS app的要求越来越高,以及已经以及今后可能出现的多种屏幕和分辨率的设备来说,Autoresizing Mask显得有些落伍和迟钝了。AutoLayout可以完成所有原来Autoresizing Mask能完成的工作,同时还能够胜任一些原来无法完成的任务,其中包括:
- AutoLayout可以指定任意两个view的相对位置,而不需要像Autoresizing Mask那样需要两个view在直系的view hierarchy中。
- AutoLayout不必须指定相等关系的约束,它可以指定非相等约束(大于或者小于等);而Autoresizing Mask所能做的布局只能是相等条件的。
- AutoLayout可以指定约束的优先级,计算frame时将优先按照满足优先级高的条件进行计算。
总结
假设有一个按钮,你想把它放置在屏幕的中央。视图中心和按钮中心的相对位置可以简
单地定义成如下:
·按钮的 center.x 相当于视图中心的 center.x
item1.attribute = multiplier ⨉ item2.attribute + constant
例如:使用这个方程式,我们可以很容易地将一个按钮放置到他的父视图中,如下所 示:
Button.center.x=(button.superview.center.x*1)+0
Button.center.y=(button.superview.center.y*1)+0
即:y = m*x + b
3.相关知识
3.1 使用线性公式添加描述
iOS6 引入类来描述约束条件:
NSLayoutConstraint NS_CLASS_AVAILABLE_IOS(6_0)
方法:constraintWithItem
[NSLayoutConstraint constraintWithItem:(id)
attribute:(NSLayoutAttribute)
relatedBy:(NSLayoutRelation)
toItem:(id)
attribute:(NSLayoutAttribute)
multiplier:(CGFloat)
constant:(CGFloat)];
(item1.attribute = multiplier ⨉ item2.attribute + constant)
NSLayoutAttribute:
typedef
NS_ENUM(NSInteger, NSLayoutAttribute) {
NSLayoutAttributeLeft = 1,
//左侧
NSLayoutAttributeRight,
//右侧
NSLayoutAttributeTop,
//上方
NSLayoutAttributeBottom,
//下方
NSLayoutAttributeLeading,
//首部
NSLayoutAttributeTrailing,
//尾部
NSLayoutAttributeWidth,
//宽度
NSLayoutAttributeHeight,
//高度
NSLayoutAttributeCenterX,
//X轴中心
NSLayoutAttributeCenterY,
//Y轴中心
NSLayoutAttributeBaseline,
//文本底标线
NSLayoutAttributeNotAnAttribute = 0
//没有属性
};
typedef
NS_ENUM(NSInteger, NSLayoutRelation) {
NSLayoutRelationLessThanOrEqual = -1,
//小于等于
NSLayoutRelationEqual = 0,
//等于
NSLayoutRelationGreaterThanOrEqual = 1,
//大于等于
};
- (NSArray *)constraints NS_AVAILABLE_IOS(6_0);
- (void)addConstraint:(NSLayoutConstraint *)constraint NS_AVAILABLE_IOS(6_0);
- (void)addConstraints:(NSArray *)constraints NS_AVAILABLE_IOS(6_0);
- (void)removeConstraint:(NSLayoutConstraint *)constraint NS_AVAILABLE_IOS(6_0);
- (void)removeConstraints:(NSArray *)constraints NS_AVAILABLE_IOS(6_0);
@end
Visual Format Syntax
The following are examples of constraints you can specify using the visual format. Note how the text visually matches the image.
- Standard Space
-
[button]-[textField]
- Width Constraint
-
[button(>=50)]
- Connection to Superview
-
|-50-[purpleBox]-50-|
- Vertical Layout
-
V:[topField]-10-[bottomField]
- Flush Views
-
[maroonView][blueView]
- Priority
-
[button(100@20)]
- Equal Widths
-
[button1(==button2)]
- Multiple Predicates
-
[flexibleButton(>=70,<=100)]
- A Complete Line of Layout
-
|-[find]-[findNext]-[findField(>=20)]-|
NSLayoutFormatAlignAllLeft = (1 << NSLayoutAttributeLeft),
NSLayoutFormatAlignAllRight = (1 << NSLayoutAttributeRight),
NSLayoutFormatAlignAllTop = (1 << NSLayoutAttributeTop),
NSLayoutFormatAlignAllBottom = (1 << NSLayoutAttributeBottom),
NSLayoutFormatAlignAllLeading = (1 << NSLayoutAttributeLeading),
NSLayoutFormatAlignAllTrailing = (1 << NSLayoutAttributeTrailing),
NSLayoutFormatAlignAllCenterX = (1 << NSLayoutAttributeCenterX),
NSLayoutFormatAlignAllCenterY = (1 << NSLayoutAttributeCenterY),
NSLayoutFormatAlignAllBaseline = (1 << NSLayoutAttributeBaseline),
NSLayoutFormatAlignmentMask = 0xFFFF,
/* choose only one of these three
*/
NSLayoutFormatDirectionLeadingToTrailing = 0 << 16, // default
NSLayoutFormatDirectionLeftToRight = 1 << 16,
NSLayoutFormatDirectionRightToLeft = 2 << 16,
NSLayoutFormatDirectionMask = 0x3 << 16,
};
[constraints addObjectsFromArray:[NSLayoutConstraint
constraintsWithVisualFormat:@"V:|-padding-[messageTextView]-kTopAndBottomPadding-|"
options:NSLayoutFormatAlignAllTop
metrics:@{@"padding":@5.0}
views:variableBindings]];
NSDictionaryOfVariableBindings(v1, v2, v3) is equivalent to [NSDictionary dictionaryWithObjectsAndKeys:v1, @"v1", v2, @"v2", v3, @"v3", nil];
*/
#define NSDictionaryOfVariableBindings(...) _NSDictionaryOfVariableBindings(@"" # __VA_ARGS__, __VA_ARGS__, nil)
UIKIT_EXTERN NSDictionary *_NSDictionaryOfVariableBindings(NSString *commaSeparatedKeysString, id firstValue, ...) NS_AVAILABLE_IOS(6_0); // not for direct use
UIView+AutoLayout (GitHub地址:https://github.com/smileyborg/UIView-AutoLayout)
这个第三方写的类别,将需要代码创建的视图的约束进行了一层封装。如果用代码设置约束的话,用可视化语言,代码量少,如果团队成员都很熟悉的情况下,可读性还行!用另一种方法创建一个个约束,然后加上view上去,虽然可读性强,但是代码量大.而这个类别就是将那些方法进行一层可读性更强的方法,和自动布局的本意一样,只要你调用简单方法去描述各个view之间的关系,而创建的约束的方法,我们不需要在去关心。作者也增加了一个数组的类别,是为了方便多个view一起创建约束使用。具体的可以直接去GitHub上下载,然后查看示例的demo。
最新文章
- CSS3 Flexbox不迷路指南
- CSS中不为人知Zoom属性的使用介绍(IE私有属性)
- Windows下设置自动关机命令
- Android第三方jar包ClassNotFind
- [3D] 基本概念
- 如何生成a1,a2,a3,a4这样的变量名
- 使用clipboard.js复制页面内容到剪切板
- 预处理C#
- LA 4728 (旋转卡壳) Squares
- jQuery 参考手册 - 事件
- js中跨域请求原理及2种常见解决方案
- C# DataTable详细用法
- 在ASP.NET Core中通过EF Core实现一个简单的全局过滤查询
- 有趣的toggleClass实现交替样式
- db2 报错 sqlcode=-420 自动类型转换的问题
- 1003: [ZJOI2006]物流运输 = DP+SBFA
- Sqlcmd使用详解
- 关于Laravel 迁移数据库的问题
- webpack 4 升级点
- unique_ptr与std::move的使用
热门文章
- OpenBLAS编译 Release x64 Win10 vs2015
- pip 安装指定版本
- 中标麒麟QT5编译出现:cannot find -lGL 和 collect2:error:ld returned 1 exit status 错误
- js文档系统-jsdoc-docdash
- ubuntu 搭建jdk1.8运行环境
- {";aa";:null} 如何能转化为 {";aa";:{}}
- git push时出现大文件的处理方法
- 【HTML5校企公益课】第二天
- smarty中常用的流程控制逻辑
- Python入门学习——PyQt5程序基本结构