初识iOS9 iPad新特性SlideView和SplitView的适配

  苹果刚发布了iOS9,在iPad上新增了两个新的特性SlideView和SplitView,前者可以在不关闭当前激活APP的情况下调出来另外个APP以30%比例显示进行操作使用,后者允许同时运行两个APP以50%50%,70%30%比例运行,感觉非常方便。

  然而,方便了用户的同时却恶心了开发者,在同一屏幕运行两种APP的时候势必APP显示比例发生改变,那么就需要对几种不同的大小进行处理,好在苹果有Autolayout,并且在iOS8中新增了SizeClass特性,两者结合,可以很好的应付以上各种情况。

  好了,为了适配iOS9上述的特性,先来看下苹果的文档说明来如何处理多种显示比例的问题。Adopting Multitasking Enhancements on iPad中对这种情况作了很好的描述,最主要的就是先理解一幅图片。

  

  在iOS8中新增的SizeClass能很好理解图片的内容,C(Compact)紧凑,R(Regular)常规,通过C和R的组合可以匹配出各种屏幕,如果不理解最直观的可以查看StoryBoard中设置Autolayout时候在底部出现的w Any h Any通过鼠标移动可以得出各种组合后能适配哪一种屏幕,这里就不再阐述。

  此图可见,在iPad标准的屏幕比例种,width和height都是R,也就是说无论横屏还是竖屏都是常规的组合即wR hR,然而在出现split和slide后状态即发生的改变,在竖屏状态下APP被分割后出现了wC hR,在横屏状态下,又出现了两种组合分别是主APP70%从APP30%和主APP50%从APP50%,通过图片得出在横屏7:3中,主APP比例是wRhR,从APP比例是wChR,在5:5情况下主从APP都是wChR,那么就此知道了APP在slideView和splitView状态下的各种高宽组合。

  总结一下APP在Slide和Split后的各种需要适配的尺寸是,100%常规状态,70%作为主APP的状态,50%作为split等分的状态,30%作为从APP出现时候的状态。由于100%和70%都属于wRhR,那么我们主要适配就分成三中情况 100%,50%,30%,如果APP界面主要以list为主或者比较简单的布局,其实只要适当调整Autolayout的offset值即可适配所有的情况,那么如果是比较复杂的界面或者需要满足各种状态下的显示怎么办呢,当然是有解决的方案,以下主要以简单代码的例子进行适配工作,主要理解原理和知道什么时候触发显示比例改变,还有种方法是通过Storyboard的SizeClass匹配上述所有状况并且逐一调整差值,这种方式比较简单用惯XIB的应该很容易解决,缺点就是维护起来稍微不方便。

  首先,有个需求,在屏幕当中放置一个红色的UIView,在正常状态下,左右两边距边框100个像素,并且有个label显示当前的比例,当出发split或者slide的时候,UIView的左右边框调整为10个像素。具体的结果如下图:

  

 

  

  上图为正常的全屏,下图为splitView之后的。

  首先代码先在view内增加一个红色的UIView和一个label用于显示当前状态。

 1      var testingView:UIView!
 2      var collectionStateLabel:UILabel!
 3
 4         testingView = UIView()
 5         testingView.backgroundColor = UIColor.redColor()
 6         self.view.addSubview(testingView)
 7
 8         collectionStateLabel = UILabel()
 9         collectionStateLabel.textAlignment = NSTextAlignment.Center
10         collectionStateLabel.textColor = UIColor.blackColor()
11         self.view.addSubview(collectionStateLabel)   

  接着,开始分析实际情况,通过模拟器或者真机使用后就会发现,在应用程序启动的时候就可能出现好几种情况,红色数字代表我的APP显示比例

  场景1 如果我正在浏览照片,这时候突然想打开APP查看某样东西的时候那么这时候就会发生几种情况。

  1 程序以SlideView启动。                                  (10:3)

  2 在通过SlideView启动后又展开到了SplitView。                        (5:5)

  3 在SplitView使用后我觉得不爽,太小了,再想进一步展开又成为全屏。            (0:10)

  场景2 如果我正在使用APP,这时候我想通过地图查看某幢楼在哪里,这时候又会发生几种情况。

  1 程序正在使用时,接受地图程序以slide方式切入,此时地图程序被激活,可以查询地图      (10:3)

  2 在查询地图的时候我还要使用回我的APP,这时候我的APP被激活,地图同样被激活          (7:3)

  3 我想放大地图程序被地图以SplitView切割成一半显示。                    (5:5)

  从上总结出来,场景1我的APP是作为从APP存在,照片是主APP,场景2我的APP是作为主APP存在,地图程序是从APP,其实这都不重要,最主要的得出结论就是在布局的时候一开始就必须考虑到针对不同的场景以适应不同的布局需求。

  现在开始代码布局,代码布局使用了一个第三方的类库以节省代码量,Apple的API实在非常的繁琐,在此使用SnapKit作为布局类库 (https://github.com/SnapKit/SnapKit),OC版本(https://github.com/SnapKit/Masonry)

从场景1,2分析出在一开始就需要知道当前的屏幕处在什么样的比例之中,那么通过文章一开始分析的Apple文档得出在slide和split下的比例都是wC hR也就是说宽是紧凑竖是标准。那么通过SizeClass的API就可以判断出来。

     if self.traitCollection.verticalSizeClass == UIUserInterfaceSizeClass.Regular && self.traitCollection.horizontalSizeClass == UIUserInterfaceSizeClass.Compact{
            //slide or split size slide和split状态
        }else{
            //regular size 标准状态
        }

  通过 UITraitCollection 类可以获取当前屏幕处在什么样子的比例当中 ,这个类封装了各种水平竖直方向等SizeClass的信息,通过实现了UITraitEnvironment接口的对象都可以拿到这个属性,(UIViewController,UIView,UIWindow,UIScreen都实现了这个接口)。通过判断属性verticalSizeClass和horizontalSizeClass的各种组合即可很容易获取到当前屏幕水平垂直配比。

  至此,屏幕显示比例判断出来了,那么就根据需求和实际情况分别编写不同比例下的适配代码即可,这里根据需求在regular下按钮左右边距100像素,在split下按钮左右10个像素。

  

    func setViewToRegularSize(){
         collectionStateLabel.text = "State:Regular View"
        guard testingView.constraints.isEmpty else{
            testingView.snp_updateConstraints { (make) -> Void in
                make.left.equalTo(self.view.snp_left).offset(100)
                make.right.equalTo(self.view.snp_right).offset(-100)
                make.centerY.equalTo(self.view.snp_centerY)
            }
            return
        }
        testingView.snp_makeConstraints { (make) -> Void in
            make.left.equalTo(self.view.snp_left).offset(100)
            make.right.equalTo(self.view.snp_right).offset(-100)
            make.centerY.equalTo(self.view.snp_centerY)
            make.height.equalTo(60)
        }
    }

    func setViewToSlideSplitSize(){
         collectionStateLabel.text = "State:SplitView or SlideView"
        guard testingView.constraints.isEmpty else{
            testingView.snp_updateConstraints(closure: { (make) -> Void in
                make.left.equalTo(self.view.snp_left).offset(10)
                make.right.equalTo(self.view.snp_right).offset(-10)
                make.centerY.equalTo(self.view.snp_centerY)
            })
            return
        }
        testingView.snp_makeConstraints { (make) -> Void in
            make.left.equalTo(self.view.snp_left).offset(10)
            make.right.equalTo(self.view.snp_right).offset(-10)
            make.centerY.equalTo(self.view.snp_centerY)
            make.height.equalTo(60)
        }
    }

  我们设置了两个函数第一个函数适配regular的情况,第二个函数适配Split或Slide的情况,并且分别在label上标注,这里使用了swift guard ... else {}来判断如果约束不为空则更新约束,否则新增约束,关于snapkit用法具体请看GIT上说明,这里仅仅举例。现在分别在初始化时候调用相应的函数即可完成APP启动时候的显示适配。并且给label上好约束。

  

        if traitCollection.verticalSizeClass == UIUserInterfaceSizeClass.Regular && self.traitCollection.horizontalSizeClass == UIUserInterfaceSizeClass.Compact{
            //slide or split size
            self.setViewToSlideSplitSize()
        }else{
            //regular size
            self.setViewToRegularSize()
        }
        collectionStateLabel.snp_makeConstraints { (make) -> Void in
            make.top.equalTo(testingView.snp_bottom).offset(50)
            make.centerX.equalTo(testingView.snp_centerX)
        }

  到了这一步已经满足了,APP从slide进来时候的适配。但是,事情还没那么简单,通过场景1,2得出,在不满足当前大小的情况下可以从slide过渡到split,甚至从split过度到regular,那么就牵涉到动态更改布局了,好在Apple的API提供了一个函数来的到当前sizeClass的改变。在viewcontroller中输入以下代码

    override func willTransitionToTraitCollection(newCollection: UITraitCollection, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
        super.willTransitionToTraitCollection(newCollection, withTransitionCoordinator: coordinator)
        if newCollection.verticalSizeClass == UIUserInterfaceSizeClass.Regular && newCollection.horizontalSizeClass == UIUserInterfaceSizeClass.Compact{
            self.setViewToSlideSplitSize()
        }else{
            self.setViewToRegularSize()
        }
    }

  这个函数类似于以前willRotateToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval)处理旋转屏幕的逻辑一样,当sizeClass发生改变后立即会得到调用,那么在这个函数内根据Apple文档提供的slide和split的比例规则也非常容易对当前布局进行更新。

  至此,我们已经完全满足了需求和场景1和2的各种情况,综上所述,只要知道sizeClass的各种比例组合就可以轻松应付各种屏幕显示发生改变的情况,再通过与Autolayout的配合,达到满足各种尺寸及动态改变尺寸需求。最后,虽然苹果引入的新的特性,看似复杂,其实还是使用老的技术来解决各种情况,sizeClass和autolayout配合犹如双剑合壁,无惧任何尺寸大小的变更。

  题外话,如果习惯使用XIB的话用法还是和之前的一样,只需要匹配各种Compact和Regular的组合并且设置好相应的约束并且Install对应的View也非常容易对付Slide和Split

  

只需要动动鼠标修改下约束也很好的满足实际的情况,只是storyboard的维护性和可读性不是很友好,代码可能会更容易做出修改维护和抽象,实际应用我代码使用的比较多点。

时间: 2024-08-01 03:47:37

初识iOS9 iPad新特性SlideView和SplitView的适配的相关文章

iOS开发——新特性OC篇&IOS9 SDK新特性

iOS9 SDK新特性 WWDC 2015苹果开发者大会是移动开发者一年一度的盛会,InfoQ中文站除了第一时间整理Keynote内容分享给大家之外,还邀请了资深的一线开发者分享他们的收获.本文为王巍(@onevcat)对WWDC上透露的iOS 9 SDK新特性的总结,分享给广大的iOS开发者. 年年岁岁花相似,岁岁年年人不同.今年的 WWDC 一如既往的热闹,得益于 Apple 的随机抽选机制,这两年有更多的中国开发者有机会亲临现场进行体验,并与全球开发者取得更多的交流.更多的开发者可能只能在

iOS开发——新特性OC篇&IOS9 系统新特性

IOS9 系统新特性 2015年6月89号凌晨召开的WWDC 2015苹果开发者大会发布了全新的iOS 9系统,PC6小编今天给大家整理了这次iOS9的系统更新带来了哪些新的功能与升级,本次新功能一览,我们分为iOS 9 for iPhone和iOS 9 for iPad两部分来介绍. 一.iOS 9 for iPhone 1.每周收到10亿条指令的Siri,在识别的速度和准确率上都提高了40%,Siri的功能也得到了丰富,可以用来查找图片.视频,也能让它提醒你看完网页上的文章. 2.为了体现智

转:iOS9的新特性以及适配方案

2015年9月8日,苹果宣布iOS 9操作系统的正式版在太平洋时间9月16日正式推出,北京时间9月17日凌晨1点推送. 新的iOS 9系统比iOS8更稳定,功能更全面,而且还更加开放.iOS 9加入了更多的新功能,包括更加智能的Siri,新加入的省电模式.iOS 9为开发者提供5000个全新的API.iOS9新的特性 这对于使用者来说固然是一个好消息,每一次版本更新带来的都是更多的便利和更全面的功能,接受新的系统固然会有一些不适应,新的系统也有可能会有一些缺陷,但是至少苹果在不断地更新,让我们体

iOS9的新特性以及适配方案-----转载

2015年9月8日,苹果宣布iOS 9操作系统的正式版在太平洋时间9月16日正式推出,北京时间9月17日凌晨1点推送. 新的iOS 9系统比iOS8更稳定,功能更全面,而且还更加开放.iOS 9加入了更多的新功能,包括更加智能的Siri,新加入的省电模式.iOS 9为开发者提供5000个全新的API.iOS9新的特性 这对于使用者来说固然是一个好消息,每一次版本更新带来的都是更多的便利和更全面的功能,接受新的系统固然会有一些不适应,新的系统也有可能会有一些缺陷,但是至少苹果在不断地更新,让我们体

iOS9 collectionView新特性

近日因为系统升级导致xcode6.系列版本出现bug,于是开始使用xcode7.在使用之余突然想到collectionView在iOS9中发布了一个可以移动cell的新特性,就尝试着将其实现,无奈api文档接口无法查看,只有一些列的api放在那里.于是上网查找,发现国内没有搜索到此类文章,于是FQ继续找,最终找到的竟然都是swift版本,于是将其转换为oc版本以帮助国内需要的朋友学习使用.下面是具体用法: 1.创建collectionView并设置代理 - (UICollectionView *

iOS9的新特性以及适配方案

1. 限制HTTP协议,全部改用更安全的HTTPS iOS9让所有的HTTP默认使用了HTTPS,原来的HTTP协议传输都改成TLS1.2协议进行传输.直接造成的情况就是App发请求的时候弹出网络无法连接.对于这个问题的解决方案,网上有一篇博客已经总结的很好了,我在这就简要的说明怎么处理这种问题. HTTPS和HTTP的区别在于哪里呢? 举个简单的栗子:原来的 HTTP 是塑料水管,容易被戳破:那么如今新设计的 HTTPS 就像是在原有的塑料水管之外, 再包一层金属水管.一来,原有的塑料水管照样

Android7.0新特性,及Android N适配

新特性部分 Android 7.0 Nougat 提供新功能以提升性能.生产效率和安全性,主要新增了以下的新特性和优化: 一.新的Notification Android N 增加了许多新的notifications API,进行了重新的设计,引入了新的风格. 模板更新: 开发者将能够充分利用新模板,只需进行少量的代码调整. 消息样式自定义: 新增自定义样式.消息回复.消息分组等更加灵活. 捆绑通知: 系统可以将消息组合在一起(例如,按消息主题)并显示组.用户可以适当地进行 Dismiss 或

iOS9 开发新特性 Spotlight使用(转)

原文:http://www.cnblogs.com/jgCho/archive/2015/11/13/4961435.html 1.Spotloight是什么? Spotlight在iOS9上做了一些新的改进, 也就是开放了一些新的API, 通过Core Spotlight Framework你可以在你的app中集成Spotlight.集成Spotlight的App可以在Spotlight中搜索App的内容,并且通过内容打开相关页面. Demo演示 2.如何集成Spotlight a.添加所需要

【干货】iOS9的新特性UI Tests

QQ群288567073,无商业广告,每日干货电子书+视频分享 荔枝FM手机客户端搜索"挨踢脱口秀"即可订阅我们 视频汇总首页:http://edu.51cto.com/lecturer/index/user_id-4626073.html 什么是UI Tests呢? UI Tests是苹果提供给我们进行UI测试的一套框架. UI Tests有什么用? 它可以通过编写代码.或者是记录用户操作过程并将其代码化,来实现自动点击某个按钮.视图,或者自动输入文字等功能. UI Tests的意义