学习目标

1.【了解】屏幕适配的发展史

2.【了解】autoResizing基本用法

3.【掌握】autoLayout 的基本用法

4.【掌握】autoLayout代码实现

5.【理解】sizeClass的基本用法

一、屏幕适配的发展史

随着iOS屏幕尺寸越来越多样化,屏幕适配也就越来越重要了。

iphone1 - iphone3gs时代,window的size固定为(320,480)。我们只需要简单计算一下相对位置就好了,不需要做屏幕适配。

iphone4 -
iphone4s时代,苹果推出了retina屏,但是给了码农们非常大的福利:window的size不变,所以也不需要做适配。

iphone5 - iphone5s时代,window的size变了(320,568)。这时AutoresizingMask派上了用场(为什么不用Autolayout?
因为还要支持ios5)。

iphone6+时代,window的width也发生了变化(相对5和5s的屏幕比例没有变化)。终于是时候抛弃AutoresizingMask改用Autolayout,因为不用支持ios5了,并且相对于屏幕适配的多样性来说autoresizingMask也已经过时了。

二、autoresizing基本用法

虽然autoresizing已经过时,但我们还是有必要了解一下的。autoResizing是苹果早期的屏幕适配的解决办法,iOS6之前完全可以胜任,因为苹果手机只有3.5寸的屏幕,在加上手机app很少支持横屏,所以iOS开发者基本不用怎么适配布局,所有的UI控件只要相对父控件布局就可以了,没错autoResizing就是一个相对于父控件的布局解决方法。autoResizing是UIView的属性,使用非常简单,但是功能远远没有autolayout那样强大。如果你的界面比较简单,要求的细节没有那么高,你也可以使用autoResizing去进行自动布局。特别注意autoResizing只能适用于控件和他父控件直接的关系,不能控制两个同层级的控件直接的关系。

在使用autoResizing进行屏幕适配,可以通过Xcode可视化的界面调整或者代码去适配。在通过Xcode可视化界面调整去适配之前,需要先去掉下图中的两个勾选(autoLayout、sizeClass)。

可以通过下图看到autoResizing通过可视化能调整的只有6根线刚好和它的6个枚举值对应。

typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) {

UIViewAutoresizingNone
     
     
    = 0,

UIViewAutoresizingFlexibleLeftMargin   = 1
<< 0,

UIViewAutoresizingFlexibleWidth  
     = 1
<< 1,

UIViewAutoresizingFlexibleRightMargin  = 1
<< 2,

UIViewAutoresizingFlexibleTopMargin  
 = 1 << 3,

UIViewAutoresizingFlexibleHeight  
    = 1 << 4,

UIViewAutoresizingFlexibleBottomMargin = 1 << 5

};

外边的4根虚线用来设置当前view距离父控件的上、下、左、右的距离是否固定不变的。

内部的2根带箭头的线来设置view是否跟随父控件来自适应width和height。

代码则可以通过(view.autoresizingMask = 枚举值)来设定autoResizing值。

autoResizing的功能仅此而已,如果我们要限制两个子控件之间的关系,他就无能为力了。这样显然不够用!!!

三、autoLayout 的基本用法

做苹果开发的一个好处是有一个很好的东家(Apple公司),他不仅很注重用户体验,而且还不忘为开发者去除一些不必要的麻烦(例如:ARC的出现...)。

autoLayout:可以在任意两个控件之间建立布局关系,可以是父子view也可以是兄弟view等。功能强大了许多,当然学习成本也高了不少。


autoLayout的基础理论:

1.view具有自我计算尺寸,布局的能力。通过它自身的内容,能够得到尺寸。

2.view的布局位置,确定于它与superview及其他view之间的关系。

3.与传统的autoresizingmask自适应相比,autoLayout更精确,能绝对的确定view的布局。

4.view不一定需要一个初始的Rect。autoLayout中,view如果有足够的约束(constraint),便可以确定自己的尺寸和位置,并且知道自己和其他view的关系。也就是想确定view的布局,就给它(们)添加约束(constraint)。

在storyboard中使用autoLayout进行屏幕适配一定要勾选Use
Auto Layout,和上面所演示的autoResizing相反。

下面用一个案例来介绍在storyboard中使用autoLayout屏幕适配的基本操作。

我们需要适配两个等宽、等高的view之间的距离永远固定。autoResizing只能适用于控件和他父控件之间的关系,不能适用于同等级的两个控件之间的关系,所以我们必须使用autoLayout来实现。

勾选Use
Auto
Layout后,在storyboard布局区域底部有三个按钮,左数第一个是设置对齐方式相关的约束,具体如下图:

左数第二个按钮是设置四个方向的约束和宽、高约束的,下图中有一个Constrain
to
margins选项,是如果我们的参考是父view的时候会屏幕边缘会有一个margin的宽度,不勾选者相当于屏幕边缘约束。

这里我让蓝色View的左、右距离父View边缘固定,并且高固定。这样得到蓝色View的(宽、x坐标、高)。还差一个y坐标,如果约束不齐全,请注意不要勾选下图绿色圈中的更新选项,保持None默认。

当我点击Add
3 Constraints后,如下图所示,有红色箭头提示,标明目前控件的约束不全。并以虚线显示出目前约束会让View将改变的位置。

选中要添加约束的控件,按住control键拖到参考控件也可以添加约束。这里我让蓝色View相当于父View垂直居中,这样y坐标也确认了,控件上的约束线都变成了蓝色,表示约束齐全并且都已经更新。如下图所示:

然后让紫色View和蓝色View左对齐、右对齐、等高,并让紫色View相当于父控件垂直居中。

修改两个View相当于父控件垂直居中对齐的偏移量一致,这样他们相对于父控件垂直居中的水平线(我也不知道咋形容,看下下图吧)距离相等。

下图就是说明垂直居中的偏移量的,水平居中也是同理。

添加约束后完成的效果图,如下所示:

四、autoLayout代码实现

其实我们在storyboard中添加的每一条约束都是一个NSLayoutConstraint对象,也就是说我们上面的案例要用代码来实现的话,需要创建好多个NSLayoutConstraint对象。不过大神总是很多的,不需要担心开发中我们使用代码来进行屏幕适配会花大量时间精力去些适配代码,有很多大神已经写好了内裤,我们直接穿上就行了。推荐一个轻量级的布局框架Masonry,GitHub地址:https://github.com/SnapKit/Masonry。虽然大神的内裤我们可以直接穿,但是代码局部的我们还是必须掌握的,不懂原理怎么穿内裤呢?学习AutoLayout之前,必须要完全抛弃传统的frame属性,先完成思想的扭转学习起来方能事半功倍。AutoLayout是苹果ios6出来的东西,与传统的Frame属性不同。每一个view对象都有一个frame属性,frame属于CGrect对象,通过苹果的Api可以得知,CGrect其实是一个结构体。

struct CGRect {

CGPoint origin;

CGSize size;

};

而AutoLayout是通过约束来实现布局的。一个view一旦使用了AutoLayout约束,那么它的frame将永远都是0,所以在使用AutoLayout之前需要两个准备工作。

1.禁用autoResizing,因为autoresizing和autoLayout是不能共存的

设置translatesAutoresizingMaskIntoConstraints为NO。


2.创建约束对象并添加约束

1.如果参考是本身才添加到本身。

2.如果参考是父控件就添加到父控件。

3.如果参考是其他控件则添加到共同的父控件。

我们通过一个案例来演示代码实现autoLayout,我们的需求是实现两个View永远等高,永远右对齐,但其中一个View的宽度是另一个View宽度的一半。需求实现后的效果如下图所示:


ViewController.m

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {

[super viewDidLoad];

//创建蓝色View并添加到父视图

UIView *blueView = [[UIView
alloc] init];

blueView.backgroundColor =
[UIColor blueColor];

[self.view
addSubview:blueView];

//创建红色View并添加到父视图

UIView *redView = [[UIView
alloc] init];

redView.backgroundColor =
[UIColor redColor];

[self.view
addSubview:redView];

//禁用autoresizing

blueView.translatesAutoresizingMaskIntoConstraints = NO;

redView.translatesAutoresizingMaskIntoConstraints = NO;

//创建蓝色View的约束

NSLayoutConstraint *blueTop =
[NSLayoutConstraint constraintWithItem:blueView
attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual
toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0
constant:30];

NSLayoutConstraint *blueLeft
= [NSLayoutConstraint constraintWithItem:blueView
attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual
toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1.0
constant:30];

NSLayoutConstraint *blueRight
= [NSLayoutConstraint constraintWithItem:blueView
attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual
toItem:self.view attribute:NSLayoutAttributeRight multiplier:1.0
constant:-30];

NSLayoutConstraint
*blueHeight = [NSLayoutConstraint constraintWithItem:blueView
attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual
toItem:nil attribute:NSLayoutAttributeHeight multiplier:1.0
constant:50];

//添加蓝色View的约束

[self.view
addConstraints:@[blueTop,blueLeft,blueRight]];

[blueView
addConstraint:blueHeight];

//创建红色View的约束

NSLayoutConstraint *redTop =
[NSLayoutConstraint constraintWithItem:redView
attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual
toItem:blueView attribute:NSLayoutAttributeBottom multiplier:1.0
constant:30];

NSLayoutConstraint *redRight
= [NSLayoutConstraint constraintWithItem:redView
attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual
toItem:self.view attribute:NSLayoutAttributeRight multiplier:1.0
constant:-30];

NSLayoutConstraint *redLeft =
[NSLayoutConstraint constraintWithItem:redView
attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual
toItem:blueView attribute:NSLayoutAttributeCenterX multiplier:1.0
constant:0];

NSLayoutConstraint *redHeight
= [NSLayoutConstraint constraintWithItem:redView
attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual
toItem:nil attribute:NSLayoutAttributeHeight multiplier:1.0
constant:50];

//添加红色View的约束

[self.view
addConstraints:@[redTop,redRight,redLeft]];

[redView
addConstraint:redHeight];

}

@end

五、sizeClass的基本用法

与其说科技的发展,拉近了空间中任意两点的距离,让交流、信息传递更加便捷。倒不如说由于交流和信息传递的需求更加迫切而推动了科技的进步。大屏显然是一典型的例子,屏幕尺寸的相对增大,一定程度上方便了交流和信息传递,反之,相对小的屏幕对信息传递会有一定的局限。所以苹果推出大屏幕的手机也是人
类进步的需要,并不是什么跟风,扯淡结束。

屏幕大了,尺寸多了,带给开发者的自然是适配方面的工作量和思考。正如大家知道的那样,苹果是一家最具追求的公司,他当然会推出可行的解决方案就是sizeClass。


sizeClass
:对屏幕尺寸进行了抽象,不在拘泥于具体尺寸。因为尺寸一直都在变化,我们如果按照尺寸去做适配,一定会很累的。

sizeClass针对iOS设备的屏幕进行了抽象分类:

compact (紧凑 - 小)、Any (任意)、Regular (宽松 - 大)。


总结几点:

1.sizeClass只是对屏幕进行了抽象分类,具体做屏幕的适配还得用autoLayout。

2.没有了横竖屏的概念,也没有了具体尺寸,不用在去谈具体的iphone6 plus还是ipad air2。

3.把高度和宽度都抽象为上边的3种,3*3也就是总共9种类型。注意是9种类型,不是9种屏幕尺寸。

这样做的结果就是你可以做好一个interface
builder适配,然后不管在iphone还是ipad中都可以用了,这就是苹果的意愿。打开xcode如果新建一个universal项目,在xcode6之前会默认有两个storyboard,一个是iphone的,一个是ipad版本的。xcode6之后只有一个,并且是正方形的,也就是说不管你做那种屏幕尺寸的app(无论是ipad还是iphone),都只用这一个storyboard就可以了。

具体分类如下:

图中9个格子代表 3*3的9中抽象,具体每种代表了那些含义可以选中看看。

比如iphone的竖屏它是这样抽象的:compact width
* regular height。

然后适配还是使用autoLayout,我就不再重复演示了,需要注意的是我们需要根据需求选择正确的sizeClass抽象屏。

iOS8加了sizeclass后,控件也多了个属性,在storyboard上托个label出来(以label为例),选中,在右边的菜单区域可以看
到:installed。这个是用来控制改控件什么情况下显示,当前什么都没约束,表示Any *
Any,就是不管是iphone什么尺寸还是ipad什么尺寸都可以显示,点击左边的小加号+可以用sizeClass控制什么情况显示。同样的还有字体、图片显示。

控制什么情况显示什么样的字体。


各种苹果设备的分辨率




各种iPhone对应尺寸






温馨提示:欢迎分享此文,分享转载请注明出处!

iOS屏幕适配-iOS笔记的更多相关文章

  1. iOS屏幕适配

    ## iOS屏幕适配 ### iOS屏幕适配发展史 1> iPhone4以前(没有iPad) * 不需要屏幕适配 2> iPad.iPhone5等设备出现 * 需要做横竖屏适配 * aut ...

  2. 【转】iOS屏幕适配

    一.iOS屏幕适配发展历程 设备 适配技术 4及以前(iPad未出) 直接用代码计算 有了iPad autoResizing 有不同屏幕的iPhone后 autoLayout 有更多不同屏幕的iPho ...

  3. Auto Layout 在iOS屏幕适配中的使用

    前几天在做iOS屏幕的适配,也就是让同样的UI控件的布局在不同屏幕的iOS设备上面都正确显示,storyBoard就无可避免的用到了Auto Layout.在这个过程中,我发现要熟练掌握Auto La ...

  4. iOS屏幕适配方案-Auto Layout

    市场上的android手机五花八门.各种尺寸的屏幕让android程序员们比較头疼. 也有一些大神写了一些博客提出了自己的观点.iOS貌似也迎来了大屏6+,因此屏幕适配的问题也是有滴,因此苹果也有自己 ...

  5. android 屏幕适配 课程笔记

    1 横竖屏切换:   文件名同样.  目录不同.   layout-port/ 代表竖屏   layout-land/ 代表横屏   layout/ 代表不论什么没有修饰符的layout目录.   终 ...

  6. 【转载】iOS屏幕适配设计

    移动app开发中多种设备尺寸适配问题,过去只属于Android阵营的头疼事儿,只是很多设计师选择性地忽视android适配问题,只出一套iOS平台设计稿.随着苹果发布两种新尺寸的大屏iPhone 6, ...

  7. iOS 屏幕适配:autoResizing autoLayout和sizeClass

    1. autoResizing autoresizing是苹果早期的ui布局适配的解决办法,iOS6之前完全可以胜任了,因为苹果手机只有3.5寸的屏幕,在加上手机app很少支持横屏,所以iOS开发者基 ...

  8. IOS - 屏幕适配

    原文:Beginning Auto Layout Tutorial in iOS 7: Part 1 感谢翻译小组成员@answer-huang(博客)热心翻译.如果您有不错的原创或译文,欢迎提交给我 ...

  9. iOS屏幕适配知识

    一.旋转处理    第一步:注册通知 [[NSNotificationCenter defaultCenter] addObserver:self                            ...

随机推荐

  1. ubuntu批量更改文件权限

    重装系统之后,把文件从windows分区拷到linux分区发现所有文件的权限全是777,在终端下看到所有文件的颜色都很刺眼,文件有很多,一个一个改不现实,所以写了一段python脚本批量更改文件权限. ...

  2. LintCode题解之统计数字

    直接硬搜就可以了,只是需要考虑k为0的情况. public class Solution { /* * @param : An integer * @param : An integer * @ret ...

  3. 什么是 Docker

    Docker 是一个开源项目,诞生于 2013 年初,最初是 dotCloud 公司内部的一个业余项目.它基于 Google 公司推出的 Go 语言实现. 项目后来加入了 Linux 基金会,遵从了 ...

  4. 拟将博客迁移到github

    其实博客园网站速度挺快的, 但是markdown的显示没有github美观. 尤其是代码高亮这一块. 近日发现github pages + vue + github api + stackedit 能 ...

  5. 个人在AS的一些安卓适配经验

    具体的安卓适配http://blog.csdn.net/qfanmingyiq/article/details/53219812 AS在屏幕适配方面做的比eclipse做得好得多. 以下AS中的一些具 ...

  6. [ExtJS6学习笔记]Ext JS6主题系列 (Classic工具包)

    本文作者:苏生米沿 本文地址:http://blog.csdn.net/sushengmiyan/article/details/50186709 翻译来源:http://docs.sencha.co ...

  7. 理解性能的奥秘——应用程序中慢,SSMS中快(1)——简介

    本文属于<理解性能的奥秘--应用程序中慢,SSMS中快>系列 在工作中发现有不少类似的现象,有幸看到国外大牛写的一篇文章,由于已经完善得不能再添油加醋,所以决定直接翻译,原文出处:http ...

  8. Racket 模拟SICP的流(延时计算)

    默认的Racket是要对函数参数进行求值的, 例如(f 1 (+ 1 2))里面,(+ 1 2)要先求值为3,变为(f 1 3)再进行下一步操作.因此, Racket若按照SICP使用define关键 ...

  9. Maven简介(Maven是什么)

    简介 Maven,在意第绪语中意为对知识的积累.Maven最初用来在Jakarta Turbine项目中简化该项目的构建过程.Jakarta Trubine项目有多个工程,每个工程都有自己的多个Ant ...

  10. Java基本语法-----java标识符

    1什么是标识符 就是程序员在定义java程序时,自定义的一些名字,例如helloworld 程序里关键字class 后跟的Demo,就是我们定义的类名.类名就属于标识符的一种. 标识符除了应用在类名上 ...