iOS 开发者的日常iOS 技术适配

iOS 8中Size Classes的使用

2016-04-21  本文已影响1039人  KenZhangCn

整理转载自:Tommy@迷糊小书童www.cnblogs.com


前言
iOS8和iPhone6发布已经过去蛮久了,广大的果粉终于迎来了大屏iPhone,再也不用纠结为大屏买三星舍苹果了…但是对于iOS开发人员来说,迎来了和Android开发开发一样的问题—>各种屏幕的适配(是不是可以要求加工资的节奏).对于适配,网传各种有关Size Class的论点,前段时间太忙,一直没去研究,套用+总的话,苹果在适配方面提供的方法做的比安卓好太多了.自己实测之后,确实很方便0.0(不过,还是想说,适配的核心始终是AutoLayout)

1418795367881579.png
概念初探
iOS8之前,公司在开发项目时,先做的iPhone版,然后要求开发iPad版本,其实内容是完全一样的,只是UI变化了,但是我们就需要建立2个工程来分别对应实现.iOS8推出的Size Class,可以让我们在一个工程的storyboard中进行所有尺寸屏幕的适配,不仅是iPhone 4s-5/5s-6-6 Plus,还包括iPad界面.它引入了一种新的概念,抛弃传统意义上我们适配时所谓的具体宽高尺寸,把屏幕的宽和高分别分成两种情况:Compact-紧凑, Regular-正常(Any-任意,其实就是这2种的组合,所以我没分成3种情况).搭配起来是3*3,也就是无论如何变化,加起来也就9种,如上图.
1.实际应用中,这Compact,Any,Regular如何运用呢?**

w:Any h:Any 是我们刚建立工程时候默认选择的,算是一切描述的父类.其他的种类描述都是在此基础上变化的,比如:如果weight设为Any,height设置为Regular,那么在该状态下的界面元素在只要height为Regular,无论weight是Regular还是Compact的状态中都会存在.于是:
w:Compact h:Compact - (w:Any h:Compact , w:Compact h:Any , w:Any h:Any)
w:Regular h:Compact - (w:Any h:Compact , w:Regular h:Any , w:Any h:Any)
w:Compact h:Regular - (w:Any h:Regular , w:Compact h:Any , w:Any h:Any)
w:Regular h:Regular - (w:Any h:Regular , w:Regular h:Any , w:Any h:Any)

2. 再来看一组数据和一张图(国外一位博主给出的,很形象):

iPhone4S,iPhone5/5s,iPhone6
竖屏:(w:Compact h:Regular)
横屏:(w:Compact h:Compact)
iPhone6 Plus
竖屏:(w:Compact h:Regular)
横屏:(w:Regular h:Compact)
iPad
竖屏:(w:Regular h:Regular)
横屏:(w:Regular h:Regular)


1418795540826221.png
3.可以总结为:

如果项目不支持横屏显示,使用w:Compact h:Regular(或者直接取消使用Size Class)
如果项目支持横屏显示,使用w:Compact h:Regular+w:Any h:Compact
对于一些公有的约束(任意组合中都适用),一般放在w:Any h:Any中设置

iPad同理

所以,我觉得Size Classes最大的帮助是,解决横屏适配和iPhone iPad共享一个设计板…(个人意见)
试验反馈一

试验反馈二
试验一里面,验证了一下概念中所列举的各个屏幕适用的组合,接下来,算是Size Classes 解决横屏的妙用


1418795836776193.png
1418796024741244.png
1418796024510371.png
1418796063111839.png

PS:运用于,横屏适配,重新排版竖屏时候的UI布局
除了改动不同组合下约束,也能改动控件在不同组合下是否显示

1418796117706089.png
1418796117427802.png

试验反馈三
AutoLayout这里不给具体如何设置,因为不知道如何写,感觉还是大家多动手去写,去试,最有效了
下面给出AutoLayout设置的图解


1418796203135811.png
1418796203676119.png

简答测试Demo结果图:


1418796267535492.png

如果不横屏,也可以直接取消Size Classes(图不一样,不同时间写的…囧)


1418796274163824.png
4.Size Classes手写代码

为了表征Size Classes
,Apple在iOS8中引入了一个新的类,UITraitCollection。这个类封装了像水平和竖直方向的Size Class等信息。iOS8的UIKit中大多数UI的基础类(包括UIScreen,UIWindow,UIViewController和UIView)都实现了UITraitEnvironment这个接口,通过其中的traitCollection这个属性,我们可以拿到对应的UITraitCollection
对象,从而得知当前的Size Class,并进一步确定界面的布局。和UIKit中的响应者链正好相反,traitCollection
将会在view hierarchy中自上而下地进行传递。对于没有指定traitCollection的UI部件,将使用其父节点的traitCollection。这在布局包含childViewController的界面的时候会相当有用。在UITraitEnvironment这个接口中另一个非常有用的是-traitCollectionDidChange:。在traitCollection发生变化时,这个方法将被调用。在实际操作时,我们往往会在ViewController中重写-traitCollectionDidChange:或者-willTransitionToTraitCollection:withTransitionCoordinator:方法(对于ViewController来说的话,后者也许是更好的选择,因为提供了转场上下文方便进行动画;但是对于普通的View来说就只有前面一个方法了),然后在其中对当前的traitCollection进行判断,并进行重新布局以及动画。代码看起来大概会是这个样子:

    - (void)willTransitionToTraitCollection:(UITraitCollection *)newCollection                  
         withTransitionCoordinator:(id <UIViewControllerTransitionCoordinator>)coordinator
    {
         [super willTransitionToTraitCollection:newCollection withTransitionCoordinator:coordinator]; 
         [coordinator animateAlongsideTransition:^(id <UIViewControllerTransitionCoordinatorContext> context) 
         {
                 if (newCollection.verticalSizeClass == UIUserInterfaceSizeClassCompact) {
                         //To Do: modify something for compact vertical size
                 } else { 
                        //To Do: modify something for other vertical size
                 } 
                 [self.view setNeedsLayout];
         } completion:nil];
    }

在两个To Do处,我们要手写代码针对不同的状态做调整。


文章整理自网络,侵删
上一篇下一篇

猜你喜欢

热点阅读