iOS 8中Size Classes的使用

作者: KenZhangCn | 来源:发表于2016-04-21 14:53 被阅读1039次

    整理转载自: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共享一个设计板…(个人意见)
    试验反馈一

    • 1.首先,先建立一个工程,展开如下页面


      1418795619564332.png

      PS:这是iOS8的新特性,真的用到项目里需要等放弃兼容iOS7 。。。显然,目前还是不行的

    • 2.在Any Any情况下,放置一个Label,并设置约束上-左-下-右为0-0-20-0


      1418795649852495.png
      1418795676961340.png
    • 3.在Compact Any情况下,又放置一个Label,并设置约束上为20


      1418795705149952.png
    • 4.继续在Compact Any情况下,来看看横屏状态下的变化


      1418795785522114.png
    • 5.最后切换到Regular Any下,完成6 Plus 的横屏显示


      1418795810496572.png

    试验反馈二
    试验一里面,验证了一下概念中所列举的各个屏幕适用的组合,接下来,算是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处,我们要手写代码针对不同的状态做调整。


    文章整理自网络,侵删

    相关文章

      网友评论

      本文标题:iOS 8中Size Classes的使用

      本文链接:https://www.haomeiwen.com/subject/gbutrttx.html