iOS开发之Auto Layout入门

随着iPhone6与iOS8的临近,适配的问题讲更加复杂,最近学习了一下Auto Layout的使用,与大家分享。

 什么是Auto Layout?

Auto Layout是iOS6发布后引入的一个全新的布局特性,其目的是弥补以往Autoresizing在布局方面的不足之处,以及未来面对更多尺寸适配时界面布局可以更好的适应。

为什么要用Auto Layout?

Autolayout能解决不同屏幕(iPhone4,iPhone5,iPad...)之间的适配问题。

在iPhone4时代开发者只需要适配一种屏幕尺寸,相比与Android阵营的相对布局,iOS开发者们最长用的做法是使用绝对布局,坐标和大小只要写死就ok了。随后iPhone5出了,对于两种屏幕尺寸,就需要考虑一个新的问题,屏幕适配。苹果其实很早就考虑到了这一点Autoresizing技术,诚然Autoresizing有所不足,苹果在iOS6发布后引入了Autolayout特性,适应更广泛场景下的布局需求。当然了iPhone5由于和iPhone4在屏幕宽度上一致,即便不用上这些技术适配起来也不麻烦(笔者再之前也只用到了Autoresizing),不过在iPhone6即将推出,即将面临更复杂的屏幕适配时,Auto
Layout能帮助我们很好地解决这个问题,此外也能解决横屏竖屏切换,iPad的适配问题。

下面是本文事例代码在横竖屏切换下的效果:

    

如何使用Auto Layout?

Auto Layout的基本概念

Auto Layout的核心是约束(constraint),通过对view的约束(view的大小,view与view之间的关系)使得view能够自己计算出尺寸和坐标。

Visual Format Language,在Auto Layout中使用的形象描述约束的一种语言规则。

Auto Layout的使用还是比较复杂的,一开始用可能会感觉云里雾里的,用的多了习惯VFL的写法之后就会感觉到它的方便了。

在代码中使用Auto Layout

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.view.backgroundColor = [UIColor greenColor];
    UIView *viewTopLeft = [[UIView alloc] init];
    UIView *viewTopRight = [[UIView alloc] init];
    UIView *viewBottom = [[UIView alloc] init];
    [viewTopLeft setBackgroundColor:[UIColor blueColor]];
    [viewTopRight setBackgroundColor:[UIColor redColor]];
    [viewBottom setBackgroundColor:[UIColor blackColor]];

    //添加约束之前必须讲view添加到superview里
    [self.view addSubview:viewTopRight];
    [self.view addSubview:viewTopLeft];
    [self.view addSubview:viewBottom];

    //对于要使用Auto Layout的控件需要关闭Autoresizing
    [viewTopLeft setTranslatesAutoresizingMaskIntoConstraints:NO];
    [viewTopRight setTranslatesAutoresizingMaskIntoConstraints:NO];
    [viewBottom setTranslatesAutoresizingMaskIntoConstraints:NO];

    //使用VFL
#if 1

    //dict和metrics相当于vfl中的名称与对象和数值的映射
    NSDictionary *dict = NSDictionaryOfVariableBindings(viewTopLeft, viewTopRight, viewBottom);
    //相当于这么写 NSDictionary *dict = @[@"viewTopLeft":viewTopLeft, @"viewTopRight":viewTopRight, @"viewBottom",viewBottom];不一定名称要与对象名一致
    NSDictionary *metrics = @{@"pad":@10};

    //水平关系(H:,可省略如vfl1),"|"相当与superview,"-"是连接符,表示两者间的间距也可以没有表示无间距
    //转化正自然语言的描述就是:superview的左边界间隔pad距离是viewTopLeft(宽度与viewTopRight相等)再间隔默认距离是viewTopRight再间隔10的距离是superview的右边界。
    NSString *vfl0 = @"H:|-pad-[viewTopLeft(==viewTopRight)]-[viewTopRight]-10-|";
    NSString *vfl1 = @"|[viewBottom]|";

    //垂直关系(V:)
    NSString *vfl2 = @"V:|-[viewTopLeft(==viewBottom)]-[viewBottom]-pad-|";
    NSString *vfl3 = @"V:|-[viewTopRight]-[viewBottom]-pad-|";

    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:vfl0 options:0 metrics:metrics views:dict]];
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:vfl1 options:0 metrics:metrics views:dict]];
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:vfl2 options:0 metrics:metrics views:dict]];
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:vfl3 options:0 metrics:metrics views:dict]];

    //不使用VFL
#else
    //viewTopLeft的leading与其superview的leading(左侧)对齐
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:viewTopLeft attribute:NSLayoutAttributeLeading multiplier:1 constant:-10]];

    //viewTopLeft的top与其superview的top对齐
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:viewTopLeft attribute:NSLayoutAttributeTop multiplier:1 constant:-10]];

    //viewTopRight的top与viewTopLeft的top对齐
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:viewTopRight attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:viewTopLeft attribute:NSLayoutAttributeTop multiplier:1 constant:0]];

    //viewTopRight的leading与viewTopLeft的trailing(右侧)对齐
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:viewTopRight attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:viewTopLeft attribute:NSLayoutAttributeTrailing multiplier:1 constant:10]];

    //viewTopRight的trailing与其superview的右侧对其
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:viewTopRight attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTrailing multiplier:1 constant:-10]];

    //viewTopRight的宽与viewTopLeft宽相等
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:viewTopRight attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:viewTopLeft attribute:NSLayoutAttributeWidth multiplier:1 constant:0]];

    //viewTopRight的高与viewTopLeft高相等
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:viewTopLeft attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:viewTopRight attribute:NSLayoutAttributeHeight multiplier:1 constant:0]];

    //viewBottom的top与viewTopRight的bottom对齐
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:viewBottom attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:viewTopRight attribute:NSLayoutAttributeBottom multiplier:1 constant:10]];

    //viewBottom的bottom与superview的bottom对齐
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:viewBottom attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1 constant:-10]];

    //viewBottom的leading与viewTopLeft的leading对齐
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:viewBottom attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:viewTopLeft attribute:NSLayoutAttributeLeading multiplier:1 constant:0]];

    //viewBottom的高与viewTopLeft的高相等
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:viewBottom attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:viewTopLeft attribute:NSLayoutAttributeHeight multiplier:1 constant:0]];

    //viewBottom的宽与其superview的高相等
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:viewBottom attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeWidth multiplier:1 constant:-20]];

#endif

    //更新约束
    [self.view setNeedsUpdateConstraints];
    [self.view updateConstraintsIfNeeded];
}</span>

注意点:

1.约束必须有给定的size然后通过约束计算出各个view的size和位置,上面self.view的size是给定的,如果superview的size不固定则必须给定某个subview的size才能通过约束计算出其他的。

2.两个view之间的约束应该放在他们superview上,如果一个view是superview只要放在superview的那个上就行了。

2.约束的设计最好不要冲突,虽然可以设置优先级,但是容易出问题。

3.VFL方式的设置view的size时只有相等,小等或大等3种关系,没法像使用方法生成约束那样可以设置两个view的比例,所以在具体的应用中还是要两者结合起来使用。

在xib中使用Auto Layout

感觉在xib中使用autolayout还没有用代码来的方便,原理与代码上相同,这里就不多做描述了。

参考资料

Auto Layout
Guide

ios8来了,屏幕更大,准备好使用 iOS Auto Layout了吗?

Autolayout及VFL经验分享

iOS开发之Auto Layout入门,布布扣,bubuko.com

时间: 2024-10-13 00:38:18

iOS开发之Auto Layout入门的相关文章

ios开发之Swift新手入门

1.关于swift和调试,swift在ios7.0才支持,ios8.3系统的真机必需要xcode6.3才干调试.安装xcode6.3需要os x 10.10以上 2.应用程序由Main.storyboard启动和设置,定义先启动哪个ViewController 3.组件有两种方式实例化.一种是直接在代码里面new出来.第二种是代码里面定义.然后在storyboard视图界面把组件加入进去.注意组件加入进去之后要进行关联. 4.注意在Build Phasses里面不能缺失Main.storyboa

Swift语言Auto Layout入门教程

Swift语言Auto Layout入门教程:上篇 开始用自动布局约束的方式思考吧! 更新记录:该教程由Brad Johnson更新Swift和iOS 8内容,原文第一版作者为教程编纂组的Matthijs Hollemans. 你可曾为了让App在横竖屏模式下都能展现整洁的界面而感到苦恼?你可曾为了让布局同时支持iPhone和iPad而感到心烦?别灰心,好消息来啦! 为某种确切尺寸的屏幕设计用户界面并不麻烦,但如果屏幕画面的框架不固定,为适应新环境,App中各个UI元素的位置和大小都需要相应调整

Swift语言Auto Layout入门教程:上篇

原文:Beginning Auto Layout Tutorial in Swift: Part 1/2,译者:@TurtleFromMars 开始用自动布局约束的方式思考吧! 更新记录:该教程由Brad Johnson更新Swift和iOS 8内容,原文第一版作者为教程编纂组的Matthijs Hollemans. 你可曾为了让App在横竖屏模式下都能展现整洁的界面而感到苦恼?你可曾为了让布局同时支持iPhone和iPad而感到心烦?别灰心,好消息来啦! 为某种确切尺寸的屏幕设计用户界面并不麻

李洪强iOS开发之iOS好文章收集

李洪强iOS开发之iOS好文章收集 该文收集朋友们转发或自己的写的技术文章,如果你也有相关的好文章,欢迎留言,当好文章多的时候,我会对这些好文章进行分门别类 文章 简述 日期 直播服务配置 使用 nginx 和 rtmp 插件搭建视频直播和点播服务器 2015-05-12 20:13:00 iOS9适配技巧 图iOS9适配新技巧 2015-09-29 09:01 TextKit分页效果 图文混排 2015年6月1日 iPhone 6 / 6 Plus 设计·适配方案 屏幕适配 2014-11-2

IOS开发之copy的问题

copy的目的就是修改副本,修改原始对象和副本时不会产生干扰. 定义一个不可变属性A,再定义一个可变属性B.用B做添加删除等操作后再将B赋值给A时,有些人习惯用A = B:其实这样是不安全的. 假设有下面的一段代码: ? 1 2 3 4 5 6 7 8 9 10   int main() {    NSMutableString *strM = [NSMutableString [email protected]"123"];    NSString *str = strM;    N

iOS开发之WKWebView简单使用和常用使用场景

iOS开发之 WKWebVeiw使用 想用UIWebVeiw做的,但是突然想起来在iOS8中出了一个新的WKWebView,算是UIWebVeiw的升级版.本着对新事物的好奇,就上网查了一下,但是找了好多个都没说的多了详细,于是就问谷歌,找文档,看看使用方法,试用了一下,果然不错,记录下来,大家分享! WKWebView的特点: 性能高,稳定性好,占用的内存比较小, 支持JS交互 支持HTML5 新特性 可以添加进度条(然并卵,不好用,还是习惯第三方的). 支持内建手势, 据说高达60fps的刷

iOS开发之CocoaPods的使用

透明色:00ff00ff //设置柱状图的颜色                ColorSet cs = new ColorSet();                cs.Id = "colorset1"; #region 设置柱状图的颜色 待开发                    string strColor = oYAXIS.Color;                    switch (strColor)                    {           

iOS开发之UILabel

UILabel是iOS开发中常用的一个组件,主要用来显示内容. UILabel的主要使用如下: ? 1 2 3 4 5 6 7 8 9 10 /*尺寸*/ CGRect labelRect = CGRectMake(100, 100, 80, 40); /*初始化*/ UILabel *titleLabel = [[UILabel alloc] initWithFrame:labelRect]; /*一些属性的设置*/ titleLabel.font = [UIFont systemFontOf

iOS开发之多XIB之间相互关联

Xib link Xib 1.直接加载xib中的UIView 创建一个View1.xib, 随便设一个背景色,加一个标识UILabel, 这样好知道是这个view是哪一个view. 你可以在这个view上加作意的subview,我只是说明原理,所以这儿并没有加作何subview. 最终我的View1如下图: 由于View1会放到其它View上作为subview,所以这儿size是Freeform, Status Bar是:None. 将下面代码放到viewDidLoad中: &1这行代码就是加载