iOS 屏幕适配:autoResizing autoLayout和sizeClass

1. autoResizing

autoresizing是苹果早期的ui布局适配的解决办法,iOS6之前完全可以胜任了,因为苹果手机只有3.5寸的屏幕,在加上手机app很少支持横屏,所以iOS开发者基本不用怎么适配布局,所有的ui控件只要相对父控件布局就可以了,没错autoResizing就是一个相对于父控件的布局解决方法;注意:它只能相对父控件布局
***
在xcode中可以通过可视化的界面调整也可以通过代码去控制

在用autoResizing的时候需要关闭autoLayout和sizeclass(如果是用xcode6)
他们之间是互相冲突的

可以通过图片看到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距离父控件的上、下、左、右的距离是否固定;
内部的两根线来设置view是否跟随父控件来自适应width和height;
代码则可以通过view.autoresizingMask = ...来设定autoResizing值;
autoResizing的功能仅此而已;显然不够用;
***
举例:
1:让两个等宽等高的view之间的间距永远固定,如图的红色view和蓝色view,想让它们之间的距离固定通过autoResizing是不行的;因为autoResizing是相对父控件进行布局的,不可以在两个兄弟view之间建立布局关系;



可以看到一个横屏和竖屏就已经不能满足需求了,更别说屏幕尺寸还要变大
当然你有可能通过其他复杂的辅助手段实现,但是很麻烦;因为不仅仅是横竖屏幕;屏幕尺寸也要变了;
autoResizing就到此为止,显然它已近过时,了解一下就可以了;
***

2. autoLayout iOS6之后

做苹果开发的一个好处是有一个很好的东家,苹果公司,他不仅很注重用户体验,而且还不忘为开发者去除一些不必要的麻烦(例如:ARC的出现...)
autoLayout:可以在任意两个控件之间建立布局关系,可以是父子view也可以是兄弟view;功能强大了许多,当然学习成本也高了不少;
如图:

为了方便了解先勾选autoLayout就可以了,sizeclass先别勾了(如果是xcode6)
autoLayout的设置功能就上图中下方的红色方框中;
***

左起第一个:


通过图中红色框圈住的地方可以看出来,该处功能是设置多个view之间的对齐方式,所以设置的时候要同时选中多个View进行设置

第二个: 

这一部分相当于是一个autoResizing,强大之处在于可以是任意两个view的相对布局,可以设置距离父控件的上下左右位置(红色框),还有自身的宽高,还可以相对其他控件设置宽高(蓝色框)

第三个:


这部分是用来添加、删除、和更新约束的,上半部分是对于选中view的约束更新,下边是容器中得所有view的约束

除了上边,还可以通过control按键配合拖线来做autoLayout,如图:

===
例子:用autolayout完成刚才autoResizing不能完成的任务,这里继续加大难度,除了让红色view和蓝色view等宽等高,而且距离始终保持不变以外,还要让两个view整体垂直居中于屏幕;先看最终的效果图

横屏效果

可以看到不管是横屏竖屏还是大屏小屏,都是没问题的,到中分线的距离固定且相等;
***
下边开始一步一步通过autoLayout完成

第一步:

先让两个view等高等宽, 在xcode中同时选中红色view和蓝色view,勾选等宽,等高;

这里也可以用另外一种方式:按住control进行拖线,为了可读性和看着直观就不用了;
这时请注意看xcode得左上角,会有红色的箭头出现,表示添加的约束不完整,先说明:约束的完整性,一个view在视图中的位置相对固定(宽高和相对位置),那么约束就完整,注意是相对固定; 而这里我们只是让两个view等宽和等高,位置在哪里并没有说明,约束当然不完整;所以有红色的错误;


知道红色的报错箭头正常之后,我们继续,添加的每一条约束都是一个实体,可以在view中看到,点击每条约束可以在xcode的右侧编辑栏中看到约束的线性公式,这个线性公式正是苹果工程师的智慧结晶,巧妙的运用数学的智慧值得我们去学习和体会;

顺着这几个文本框从上往下读可以得到如下的线性公式(Priority优先级不算入公式):
view.width Equal view.width * 1 + 0
化解得:
view.width = view.width 就这样实现了两个view之间的width关系的描述,将这个公式转化成代码应该很easy吧.. 哈哈

说明:这里我们查看的是width约束,所以是view.width,两个view可以分别认为是红色view和蓝色view,可以相互对调位置
也许上边不伦不类的公式很难理解,那么假设红色view的宽度为x, 蓝色view的宽度为y,对于任意两个实数x,y,都可以用下面的线性公式(或者说是一次线性函数)表示他们之间的关系:
y = k·x + b 其中k是系数(就是上图中的Multipliter), b是常数(是上图中的Constant);
就是这个小学已经学习过的一次函数,可以满足任何两个view的任何边距关系;



第二步:
了解这些之后,回到正题,刚才只是添加了两个view等宽等高,接下来,为了保证不会错乱,我们可以一个一个的来完成约束,这里先固定红色的view:
这里采用control拖线的方式:

这里我们让红色view和蓝色的centerY到父view的centerY都是70,这样操作后相当于两个view在竖直方向上的位置固定;水平方向和每个view的快高具体是多少都还没固定;所以xcode左上角继续报红色错误
第三步:
固定水平位置和宽高,这里固定宽高,只需要固定其中的一个即可,因为两个view的宽高相同;

可以看到添加完后红色的箭头变成了黄色,这表示,约束完整只差一步update了,这是你可以通过点击黄色箭头update或者如图:

好了,到此就搞定了;这个看似只有两个view,但是这个需求已经是相对复杂了;

案例二:
通过上边的案例一可以看出autoLayout可以设置任意两个view之间的约束,可以说能实现任何想要布局;
下边的案例:让四个view始终等分屏幕:
效果图(为了说明效果,中间留了一个像素的间距):

思路:先固定好其中的一个,然后其他view和这个view等宽等高,然后设置相对父控件的约束;

代码实现autolayout

每一条约束都是一个:NSLayoutConstraint对象

NSLayoutConstraint *layout = [NSLayoutConstraint constraintWithItem:(id)
attribute:(NSLayoutAttribute) relatedBy:NSLayoutRelationEqual toItem:(id)
attribute:(NSLayoutAttribute) multiplier:(CGFloat) constant:(CGFloat)];
[self.view addConstraint:layoutConstraint]

该方法正是刚才线性公式 y = k·x + b 的代码表示;所以虽然很长,但是很容易读懂;最后要记得把约束添加到view上,添加的时候必须要注意如果这个约束是父子view关系,约束必须加在父view上边;
但是用代码去实现autolayout实在是麻烦,刚才的两个例子,每个例子中得约束有15个以上,如果用代码实现,要创建15个以上的NSLayoutConstraint对象,还有弄清楚关系,不能写错;苹果又为开发者考虑到了这一点;于是推出了为了写autolayout方便的VFL语言;

VFL

严格来讲不算语言,一中语法类似正则表达式的专门用来写autolayout的;但是vfl并没有带来简化,其繁琐程度基本上是写一行就不想写第二行的程度:

NSString *vfl1 = @"|-hPadding-[_headerL]-hPadding-|";
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:vfl1
options:0 metrics:metrics views:dict1]];   

和正则用法差不多,先用字符串写一些匹配规则,然后就调用后边的方法去解析这个规则到view上;我个人一直认为编程语言应该从简,将复杂的东西屏蔽掉,使我们开发起来更高效,也有更多时间去处理好业务; 毕竟我们每天做的情就是让用户简单起来,把复杂留给自己;所以vfl不用也罢;

一个label用autoLayout约束,会自动计算好宽高,并且上边和下边不会留空白;

3. 苹果界面设计的统一:sizeClass

与其说科技的发展,拉近了空间中任意两点的距离,让交流、信息传递更加便捷;倒不如说由于交流和信息传递的需求更加迫切而推动了科技的进步;大屏显然是一典型的例子,屏幕尺寸的相对增大,一定程度上方便了交流和信息传递,反之,相对小的屏幕对信息传递会有一定的局限;所以苹果推出大屏幕的手机也是人类进步的需要,并不是什么跟风,扯淡结束;
屏幕大了,尺寸多了,带给开发者的自然是适配方面的工作量和思考;正如大家知道的那样;苹果是一家最具追求的公司,他当然会推出可行的解决方案就是sizeClass;
sizeClass: 对屏幕尺寸进行了抽象:不在拘泥于具体尺寸;因为尺寸一直都在变化,我们如果按照尺寸去做适配,一定会很累的;

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

  1. compact (紧凑-小)
  2. Any (任意)
  3. Regular (宽松-大)

总结几点:

  • sizeClass只是对屏幕进行了抽象分类;具体做屏幕的适配还得用autoLayout;
  • 没有了横竖屏的概念,也没有了具体尺寸,不用在去谈具体的iphone5还是ipad air;
  • 把高度和宽度都抽象为上边的3种,3*3也就是总共9种类型;是9种类型,不是9种屏幕尺寸;

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

    了解3种抽象:

    xcode中得样子:

    ***
    具体来看:

图中9个格子代表 3*3的9中抽象;具体每种代表了那些含义可以选中看看;
比如iphone的竖屏它是这样抽象的:compact width * regular height

通过sizeclass对屏幕进行分类,然后用autolayout去适配布局,可以说能实现任何想要的效果,并且不用区分设备而做不同的IB了,一个IB全部搞定,不管是iphone还是ipad;
案例:

有个view 100 * 100,在iphone竖屏时居于左上角,横屏时在右下角,ipad中在正中间;

像这种过去看来变态的要求,在现在来说小菜一碟;

  • 步骤一:处理竖屏情况
    先用sizeclass固定屏幕为iphone竖屏:compact Width | Regular Height

    然后添加view到ib上,用autolayout固定尺寸100 * 100;并且在左上角;这里让它居左20,居上20;

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

    在不同的屏幕下显示不同的字体:

    ... 类似的功能还有很多
    这个功能的思想和UIButton的三种状态(normal, highlighted, selected)类似,只不过这里有9种状态;
    ***

    xcode6预览

    当屏幕种类变的越来越丰富的时候,如果要查看不同屏幕之间的适配情况,在过去是要不停的切换模拟器,然后运行看效果的,而切换模拟器是很耗时的一件事;xcode6之后,我们可以不用运行直接查看适配的情况;
    对于刚才的事例进行如图操作即可不运行查看适配效果;

代码预览 @

这两个属性是xcode6新出的特性
如果不是通过IB创建view,而是通过代码创建的View,如何在不运行程序的情况下实时的渲染在IB上呢,;@IBDesignable告诉Interface Builder这个类可以实时渲染到界面中,但是这个类必须是UIView或者NSView的子类。,即可在attribute inspector面板中可视化修改属性值。

示例(swift编写): 这个例子自定义一个UIView的子类,该子类拥有一个UIButton

@IBDesignable
class MyCustomView: UIView {
  @IBInspectable var buttonTitleColor: UIColor! //  button title color
  @IBInspectable var buttonTitle: String!	    //  button title
  @IBInspectable var buttonFrame: CGRect!	    //  button frame
  var myButton: UIButton!

  override init(frame: CGRect) {
    // init stored properties
    buttonTitleColor = UIColor.redColor()
    buttonTitle = "我是按钮"
    buttonFrame = CGRectMake(0, 0, 100, 50)

    myButton = UIButton(frame: buttonFrame)
    myButton.setTitleColor(buttonTitleColor, forState: .Normal)
    myButton.setTitle(buttonTitle, forState: .Normal)

    // call super initializer
    super.init(frame: frame)

    // add button to self
    addSubview(myButton)

  }
  required init(coder aDecoder: NSCoder) {
    // init stored properties
    buttonTitleColor = UIColor.redColor()
    buttonTitle = "button title"
    buttonFrame = CGRectMake(0, 0, 100, 50)

    myButton = UIButton(frame: buttonFrame)
    myButton.setTitleColor(buttonTitleColor, forState: .Normal)
    myButton.setTitle(buttonTitle, forState: .Normal)

    // call super initializer
    super.init(coder: aDecoder)

    // add button to self
    addSubview(myButton)
  }

  override func layoutSubviews() {
    // refresh button state through attribute inspector
    myButton.setTitleColor(buttonTitleColor, forState: .Normal)
    myButton.setTitle(buttonTitle, forState: .Normal)
  }
}

该类在界面上加了一个Button,并且添加了三个属性,颜色、title、frame;这三个属性都是用来描述button的,,不用运行程序启动模拟器即可;
同时还重写drawRect方法画了一个矩形;
这个时候打开storyboard,添加一个View(为了控制gif图的大小,图中的View事先加好了约束,并且背景色改为蓝色,方便识别);修改class为MyCustomView;预览就会出现;同时我们将开始画得矩形改为椭圆,然后再次查看storyBoard,预览已经变为椭圆,真是太爽了,不用在浪费时间等待模拟器启动去观察UI的布局了;

各种苹果设备的尺寸和分别率

一图胜千言

***

时间: 2024-10-11 17:36:24

iOS 屏幕适配:autoResizing autoLayout和sizeClass的相关文章

iOS开发UI篇—屏幕适配autoResizing autoLayout和sizeClass图文详解

1. autoResizing autoresizing是苹果早期的ui布局适配的解决办法,iOS6之前完全可以胜任了,因为苹果手机只有3.5寸的屏幕,在加上手机app很少支持横屏,所以iOS开发者基本不用怎么适配布局,所有的ui控件只要相对父控件布局就可以了,没错autoResizing就是一个相对于父控件的布局解决方法:注意:它只能相对父控件布局:***在xcode中可以通过可视化的界面调整也可以通过代码去控制 在用autoResizing的时候需要关闭autoLayout和sizeclas

屏幕适配Autoresizing / Autolayout / Mansory / 自定义Frame实现

1. 什么是适配: 适应.兼容不同版本不同尺寸的移动智能设备 iPhone尺寸:3.5.4.0.4.7.5.5inch iPad尺寸:7.9.9.7inch,横竖屏适配 2. 点与像素 非retaina屏:1个点 = 1个像素 retain屏:1个点 = 4个像素 3. 什么是Autolayout 1>  是一种“自动布局”技术,专门用来布局UI界面的 2> 自iOS 6开始引入,由于Xcode 4的不给力,当时并没有得到很大推广 3> 自iOS 7(Xcode 5)开始,Autolay

iOS开发——屏幕适配篇&amp;autoResizing autoLayout和sizeClass

autoResizing autoLayout和sizeClass详解 1. autoResizing autoresizing是苹果早期的ui布局适配的解决办法,iOS6之前完全可以胜任了,因为苹果手机只有3.5寸的屏幕,在加上手机app很 少支持横屏,所以iOS开发者基本不用怎么适配布局,所有的ui控件只要相对父控件布局就可以了,没错autoResizing就是一个相对于父控件的布 局解决方法:注意:它只能相对父控件布局:***在xcode中可以通过可视化的界面调整也可以通过代码去控制 在用

iOS屏幕适配

一.iOS屏幕适配发展历程 设备 适配技术 4及以前(iPad未出) 直接用代码计算 有了iPad autoResizing 有不同屏幕的iPhone后 autoLayout 有更多不同屏幕的iPhone后 sizeClass 二.各个技术的特性 1. 直接用代码计算 由于屏幕的大小都一样,只有横竖屏的情况,可以直接计算 2. autoResizing 适合于控件与其父控件的关系 各属性的解释 属性 解释 UIViewAutoresizingNone 不会随父视图的改变而改变 UIViewAut

iOS屏幕适配(续)

上一篇博客总结了iOS屏幕适配的若干技巧,本文再补充几点别的方面 设计图 一般会先由美工做出界面的设计图,然后开发再去实现.上一篇博客说的主要是,开发怎么实现的问题.实际上从设计图这个环节,就需要开始考虑界面适配的问题.主要是2点: 1.出几张图 如果以iPhone6为基准出设计图的话,一般很难完美地适配到iPhone4,5和6P上,因为屏幕尺寸差异很大.一般在6上摆得很紧凑好看,在4和5上就会摆不下(溢出屏幕),在6P上则会有比较大的空隙 通常有几种办法: 设计元素的位置和大小,不用具体的数值

iOS 屏幕适配之sizeclass

1. 屏幕适配的各种技术 1> 3gs\4\4s时代:没有屏幕适配一说,尺寸只有一个,直接用代码计算frame就行了 2> iPad出现:为应对横竖屏,苹果推出autoresizing,它的作用是让子控件能跟随父控件做拉伸.如下图,autoresizing可以让红色的子控件的宽度始终铺满屏幕 3> 5\5c\5s的出现:autoresizng不够用了,因为它只能解决父子关系控件的排布问题,解决不了兄弟关系控件之间的位置关系,所以autolayout出现了. autolayout,可以在任

iOS中的屏幕适配之Autolayout(初级)

这是第二篇博客啦啦啦,来来来,嗨起来,今天我们要说的时iOS的屏幕适配,随着APPLE推出的手机越来越多,屏幕的尺寸也越来越多,而屏幕的适配确是相当的麻烦,今天我要说的,网上也许早就有了,我只是说出自己的理解(可能不对啊,勿喷....) Autolayout其实就是约束了,今天讲得是代码添加约束,用到的第三方是Masonry,相信代码写约束的都知道这个第三方库,好了,废话不多说,代码搞起 首先你要去下载个Masonry,或者用cocoapods加到工程中,先来个简单点得例子啊,下面请重点看注释啊

autoResizing autoLayout和sizeClass

原文网址: http://www.cnblogs.com/cxbblog/p/4166876.html 1. autoResizing autoresizing是苹果早期的ui布局适配的解决办法,iOS6之前完全可以胜任了,因为苹果手机只有3.5寸的屏幕,在加上手机app很 少支持横屏,所以iOS开发者基本不用怎么适配布局,所有的ui控件只要相对父控件布局就可以了,没错autoResizing就是一个相对于父控件的布 局解决方法:注意:它只能相对父控件布局:***在xcode中可以通过可视化的界

iOS屏幕适配的几种方式

屏幕适配问题共有四种解决方案:(1)根据屏幕宽高写控件frame(下策);(2)Autoresizing的使用(中策);(3)AutoLayout的使用(上策);(4)sizeClasses+AutoLayout的使用(上上策).下面将会分别来进行叙述. (1)根据屏幕宽高写控件frame 利用宽高比,在不同的屏幕中来进行对控件的位置与控件的宽高进行等比例缩放.选定一个型号的屏幕的宽高为基准,进行等比例缩放.例如以iPhone6或者iPhone6s为基准. 其宽高分别是375与667.Iphon