文档章节

从此爱上iOS Autolayout

hejunbinlan
 hejunbinlan
发布于 2016/08/01 13:33
字数 2639
阅读 9
收藏 0
点赞 0
评论 0

这篇不是autolayout教程,只是autolayout动员文章和经验之谈,在本文第五节友情链接和推荐中,我将附上足够大家熟练使用autolayout的教程。这篇文章两个月前就想写下来,但因为一直工作较多,没有时间来完成。今天终于狠下心,丢下代码不写,来完成他吧!

一、别和我提Autolayout,我想死!!

从iOS6/xcode4开始,苹果开始提供了autolayout——一种对不同屏幕尺寸有更好兼容的自动布局机制,但我相信大多数人在刚接触autolayout时,一定和我一样,几乎快被其折磨致死!

autolayout因为布局思路与传统frame有所不同,国内关于autolayout的教程有过少,且autolayout在刚上手时灵活性不易掌控,导致大家更多选择了放弃。

二、为啥我要用autolayout?

随着3.5寸/4寸iPhone在市面同时使用越来越多,以及即将上市的iPhone6、iPhone6 Plus,不同尺寸、不同分辨率的iOS设备将会越来越多,使用传统frame布局的工作量必将越来越大;加上苹果发出的信号,使用autolayout势在必行。

好了,我该来表扬表扬autolayout了,它到底能解决什么问题,给我们带来哪些好处?
1)你基本上可以不用考虑3.5寸和4寸以及即将上市的x.x寸屏幕不同分辨率的问题,你终于可以不用在viewDidLoad方法里判断不同分辨率下,不同控件应该放在哪里,或者针对不同分辨率写不同的storyboard和xib;
2)你可以抛弃那些根据不同文字来计算tableViewCell、UILabel高度的代码了,因为autolayout会帮你自动计算好;
3)如果你的布局在横屏竖屏下变化不是特别大,你不用再为横着竖着写两套代码或者写两个storyboard/xib了;
4)对于即将上市的4.7寸和5.5寸iPhone,你基本上能很快甚至不用动一行代码就完成他们的自适应屏幕布局,不用每次来了新分辨率,你只能say f*ck,然后改两个通宵。

再看看苹果的态度,默认就是选择了使用autolayout。虽然我现在仍有时会骂autolayout,但我还是会坚决地选择走上这条道路。

三、Autolayout之折腾二三事

刚刚表扬完autolayout,那我得为和我一样,愿意选择走上这条道的同志们提点醒了,你究竟要做好哪些折腾的准备。

3.1.布局思维的转变

传统布局思路中,一个view在哪里有多大,那就写清楚它的坐标位置和宽高就定了,平时用CGRect和CGPoint这两种模型就足够了,而且它一定非常听你的话,写的是多少,它绝对就是多少;但是autolayout的思路却变化了,或者说改进了,它囊括了传统frame布局思路,除了可以告诉view的坐标和宽高,它更提供了一种相对的概念,比如:
1)view相对于屏幕视图左边5点,右边10点,上面15点,下面20点,如果屏幕的长宽比例发生了改变(比如从3.5寸的320:480变成了4寸的320:568,或者从横屏切换到了竖屏),view仍然会随着屏幕的比例而拉伸改变,仍然保持离屏幕视图左边5点,右边10点,上面15点,下面20点;
2)view1和view2之间相距10点,当屏幕尺寸发生改变或者旋转时,他俩仍然可以通过改变自身的尺寸或位置改变来保证它们中间就是相距10点;
3)...
所以,使用autolayout的第一步是你需要考虑它相对于superView或者brotherView的上下左右的距离,改变自己布局的思维。

3.2.使用autolayout可能会经常得到自己不想看到的样子,而且你改变frame还没用

frame时代,是你写的多少位置点就是多少位置点,view不会被自动的拉伸或者改变位置,但是autolayout中的view却会根据屏幕长宽比或者其他view的改变而改变,你经常就会看到被自动布局成了不是你想的样子,这也是太多人被折磨的原因。只要你考虑的相对的位置不正确,它真的就可能会乱掉。

3.3.autolayout的VFL(Visual Format Language)语法初看起来真蛋疼

好吧,既然使用了autolayout,使用frame来改变位置不起作用了,那我也用代码来完成autolayout总行了吧。但是,让我选一段最普通的VFL代码给你看看:

NSString *vfl = @"V:|-5-[_view]-10-[_imageView(20)]-10-[_backBtn]-5-|";

纳尼?!这是什么地干活?!我又要付出学习成本了啊!!!其实这段话就是说,在垂直方向从上到下,view离父视图5点,imageView距离view 10点,同时imageView是20点高,backBtn离imageView底部10点,距离父视图底部5点。

3.4.手动Constraint书写,那个长长长啊~~

当然,你还可以一个一个的写布局约束Constraint,就和frame分别指定origin和size类似,但是却像这样:

[self.view addConstraint: [NSLayoutConstraint constraintWithItem:blueView
attribute:NSLayoutAttributeLeft
relatedBy:NSLayoutRelationEqual
toItem:redView
attribute:NSLayoutAttributeLeft
multiplier:1
constant:0]];

而上文中的“view离父视图5点,imageView距离view 10点,同时imageView是20点高,backBtn离imageView底部10点,距离父视图底部5点”每一个逗号短句都是像这样的一个constraint。

四、你是不是已经准备放弃了?NO!说好的爱上Autolayout呢!

写到这里,我忽然觉得我是在黑autolayout了,不,看我的题目,我是真的已经爱上使用autolayout了。就让我来说说应该怎么使用autolayout。

4.1.autolayout一般应用步骤和最适宜场景

当你的页面不会变更整体布局和设计,只有在不同屏幕尺寸、不同文字和内容下有适应性的变化,那这种情况使用autolayout就再适宜不过了。不会在像frame的时代,苦逼的要为不同屏幕尺寸计算各自的位置点坐标和大小了。通常使用xcode->Editor->Pin/Align菜单为视图添加约束即可。一般通过InterfaceBuilder确定控件位置,当存在需要自动被拉伸、适应或位移的控件时就要添加constraint;具体使用教程可参考《开始iOS 7中自动布局教程1》

4.2.你的视图有比较简单的布局改变

当需要产生比较简单动画或动态添加视图时,autolayout还算好用。通常有两种方式:
1.在Controller中像声明UIView的IBOutlet一样,声明一个Constraint属性,例如XXViewTopConstraint.当进行布局变化时,直接修改XXViewTopConstraint的constant属性,即可改变其相对位置。然后再来一句

[self.view layoutIfNeeded];

搞定!
2.通过Constraint的优先级(Priority)来变更视图相对布局。如过是两条同样描述距离superview上边缘距离的约束,如果这两个约束的数值不同,但是优先级一样,则autolayout将报布局冲突,将会丢弃某一条约束(这时可能就会丢弃你想要的约束,而恰恰保留了你不想看到的布局)。所以,当我们发生布局变化时,无法像frame的绝对定位,直接改变,并且只有唯一的位置信息。那么,我们该怎么处理这种布局冲突呢?那就是让描述相同但数值不同的这两个约束采用不同的优先级。autolayout默认将使用数值较大的优先级约束。

通常1就能搞定大部分问题,2的情况较少,但有时有奇效!

4.3.你的视图有较为复杂的动画效果或者较大的布局改变

虽然autolayout可以完成所有的布局问题,但它仍然在某些情况下是不方便的,就像4.2节描述的,你的每一行代码只能改变一个constraint,但要知道每个视图通常需要4个甚至更多constraint来约束,所以一旦有较为复杂的布局改变和动画,那你可能需要写好几行,但是frame一行代码就可以搞定。
并且,好几行代码还不是最要命的,要命的是你可能还需要给这每一个约束声明IBOutlet,或者通过view的constraints属性,从constraints数组里判断出对应方向、大小的约束,再改值,真心好折腾!
所以,当你需要非常频繁的变更控件布局,并且变更的位置是不确定的(例如通过手势拖动一个视图到屏幕任意位置),那么,我建议此视图不要使用autolayout,而使用frame的所写即所得的绝对定位方式更好,你只需要充分考虑各种屏幕适配,并为其计算适合的坐标点即可。同时,我还建议这种频繁变更的视图甚至不要InterfaceBuilder来绘制,最好直接代码书写,因为一旦你勾选了autolayout,那么storyboard中的所有视图都将autolayout。当你需要变更视图布局时,则必须使用
view.translatesAutoresizingMaskIntoConstraints = NO;
superview.translatesAutoresizingMaskIntoConstraints = NO;
来避免为你的视图新增默认autolayout约束。

五、友情链接和推荐

1.《开始iOS 7中自动布局教程1》
这个教程看完基本上可以比较熟悉的使用autolayout,再结合本文的一些经验,应该能够解决大部分问题了。而该文的教程2没有中文翻译,只有英文原版:《Beginning Auto Layout Tutorial in iOS 7: Part 2》
2.《Autolayout及VFL经验分享》
这篇文章以较简单的描述囊括了VFL使用方法和常用的autolayout技巧。足够大家使用了。
3.《AutoLayout(自动布局)入门》
这篇文章精简的囊括了autolayout的代码操作方式。
4.《Auto Layout 使用心得》
作者JohnLui囊括了autolayout最常用的使用场景,描述清晰详细,使用swift实现,实用性超强。

如果在通读了本文和以上链接后还无法灵活运用autolayout,欢迎给我留言,大家一起讨论!同时欢迎关注我的博客http://www.ilikewhite.com和微博http://weibo.com/ilikewhite

本文转载自:https://segmentfault.com/a/1190000000646452

共有 人打赏支持
hejunbinlan
粉丝 40
博文 532
码字总数 21018
作品 0
浦东
高级程序员
面试官自述:面向高级开发人员的iOS面试问题

当您准备进行技术性iOS面试时,了解您可能会询问哪些主题以及经验丰富的iOS开发人员期望什么是非常重要的。 这是许多硅谷公司用来衡量iOS候选人资历水平的一系列问题。 这些问题涉及iOS开发的...

菇哒微课 ⋅ 04/26 ⋅ 0

如何判断你是合格的高级iOS开发工程师?

前言 随着移动互联网的高速发展泄洪而来,有意学习移动开发的人越来越多了,竞争也是越来越大,需要学习的东西很多。如何才能在激烈的移动开发者竞争中一枝独秀,成为一名真正合格的高级iOS...

_小迷糊 ⋅ 05/26 ⋅ 0

iOS一些代码的取巧写法总结(二)

一、在xib/storyboard里面设置view圆角半径 在xib/storyboard里面设置view圆角半径 神奇的IB_DESIGNABLE和IBInspectable(xib中设置圆角) 二、push pop 动画突然消失的解决方案 产生的原因是动...

朝雨晚风 ⋅ 2016/12/05 ⋅ 0

你知道我为什么特别讨厌程序员吗?

你知道我为什么特别讨厌程序员吗? 2018-05-28 11:20编辑: 枣泥布丁分类:程序人生来源:程序师 程序员修电脑装系统 招聘信息: C++工程师 Cocos2d-x游戏客户端开发 iOS开发工程师 京东招聘...

枣泥布丁 ⋅ 05/28 ⋅ 0

【AR】开始使用Vuforia开发iOS(2)

原 设置iOS开发环境 安装Vuforia iOS SDK 如何安装Vuforia iOS示例 编译并运行Vuforia iOS示例 支持iOS金属 iOS 64位迁移 设置iOS开发环境 适用于iOS的Vuforia引擎目前支持运行iOS 9及更高版...

lichong951 ⋅ 06/11 ⋅ 0

HDU ~ 6297 ~ CCPC直播 (模拟,输出格式控制)

思路:模拟就行了,注意Running和RTE的开头字母一样。 iomanip是I/O流控制头文件,就像printf的格式化输出一样。 以下是一些常用的: dec 置基数为10 相当于"%d" hex 置基数为16 相当于"%X" oc...

zscdst ⋅ 05/29 ⋅ 0

苹果对体无完肤的 iOS 11 最后的弥补

点击上方“CSDN”,选择“置顶公众号” 关键时刻,第一时间送达! 距离万众瞩目的苹果开发者大会(WWDC 2018)的召开还有不到一周时间,苹果公司于今天凌晨,正式发布了 iOS 11 的第十四次更...

csdnnews ⋅ 05/30 ⋅ 0

天生不凡ios怎么在电脑上玩 天生不凡ios电脑版玩法教程

天生不凡ios怎么在电脑上玩呢?现在有很多小伙伴都在玩天生不凡手游,不过相对于传统的在手机上进行游戏,很多人都倾向于新玩法,就是在电脑上玩天生不凡手游。下面小编就给亲们介绍下天生不...

kaopu8520 ⋅ 05/29 ⋅ 0

赛诺:Q1中国智能机销量OPPO居首 华为荣耀分列四五位

赛诺:Q1中国智能机销量OPPO居首 华为荣耀分列四五位 2018-04-24 17:06编辑: 游星啊分类:业界动态来源:新浪科技 智能机智能机市场智能机销量 招聘信息: C++工程师 Cocos2d-x游戏客户端开发...

游星啊 ⋅ 04/24 ⋅ 0

Dhar/YTTInjectedContentKit

YTTInjectedContentKit iOS壳版本场景下的批量修改类名、属性名、插入混淆代码、修改项目名称的shell脚本 具体的实现和使用方法请参考我的博客文章: iOS使用shell脚本注入混淆内容 iOS使用S...

Dhar ⋅ 05/04 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

一张图看懂CDN全站加速产品解决方案

原文链接 本文为云栖社区原创内容,未经允许不得转载。

阿里云云栖社区 ⋅ 14分钟前 ⋅ 0

一张图看懂CDN全站加速产品解决方案

原文链接

猫耳m ⋅ 15分钟前 ⋅ 0

开启Swarm集群以及可视化管理

在搭建的两台coreos服务器上开启swarm集群 前置条件: docker均开启2375端口 同一个局域网内 主服务器上安装Portainer容器 安装Portainer容器执行: docker run -d -p 9000:9000 --restart=a...

ykbj ⋅ 33分钟前 ⋅ 0

单例设计模式

1、单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例 2、饿汉式单例类 在这个类被加载时,静态变量instance会被初始化,此时类的私有构造子会被调用 饿汉式是典型...

职业搬砖20年 ⋅ 38分钟前 ⋅ 0

前端基础(四):前端国际规范收集

字数:1142 阅读时间:5分钟 前言 由于前端技术的灵活性和杂乱性,导致网上的许多解决方案不够全面甚至是完全错误,容易起到误导作用。所以,我对搜索到的解决方案往往是存疑态度。那么,如何...

老司机带你撸代码 ⋅ 40分钟前 ⋅ 0

Failed to open/create Network-VirtualBox Host-Only

虚拟机版本 : Oracle Vm VirtualBox 5.2.12 报错时机:开网卡二,重启虚拟机报错 "Failed to open/create the internal network 'HostInterfaceNetworking-VirtualBox Host-Only Ethernet Ada......

p至尊宝 ⋅ 43分钟前 ⋅ 0

springMVC接收表单时 Bean对象有Double Int Char类型的处理

前台ajax提交表单price为double类型 后台controller就介绍不到 400错误 前台 实体类: public class ReleaseMapIconConfig{ private String id; private long maxValue; private long minVal......

废柴 ⋅ 49分钟前 ⋅ 0

ZOOKEEPER安装

工作需要在ubuntu上配置了一个zookeeper集群,有些问题记录下来。 1. zookeeper以来java,所以首先要安装java。但是ubuntu系统有自带的jdk,需要通过命令切换java版本: $ sudo update-alter...

恰东 ⋅ 52分钟前 ⋅ 0

linux 进程地址空间的一步步探究

我们知道,在32位机器上linux操作系统中的进程的地址空间大小是4G,其中0-3G是用户空间,3G-4G是内核空间。其实,这个4G的地址空间是不存在的,也就是我们所说的虚拟内存空间。 那虚拟内存空间...

HelloRookie ⋅ 52分钟前 ⋅ 0

myatis #{}与${}区别及原理

https://blog.csdn.net/wo541075754/article/details/54292751

李道福 ⋅ 55分钟前 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部