国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

初識iOS9iPad新特性SlideView和SplitView的適配

2019-11-14 18:16:45
字體:
供稿:網(wǎng)友

  蘋果剛發(fā)布了iOS9,在ipad上新增了兩個新的特性SlideView和SplitView,前者可以在不關(guān)閉當(dāng)前激活A(yù)PP的情況下調(diào)出來另外個APP以30%比例顯示進(jìn)行操作使用,后者允許同時運(yùn)行兩個APP以50%50%,70%30%比例運(yùn)行,感覺非常方便。

  然而,方便了用戶的同時卻惡心了開發(fā)者,在同一屏幕運(yùn)行兩種APP的時候勢必APP顯示比例發(fā)生改變,那么就需要對幾種不同的大小進(jìn)行處理,好在蘋果有Autolayout,并且在iOS8中新增了SizeClass特性,兩者結(jié)合,可以很好的應(yīng)付以上各種情況。

  好了,為了適配iOS9上述的特性,先來看下蘋果的文檔說明來如何處理多種顯示比例的問題。Adopting Multitasking Enhancements on iPad中對這種情況作了很好的描述,最主要的就是先理解一幅圖片。

  

  在iOS8中新增的SizeClass能很好理解圖片的內(nèi)容,C(Compact)緊湊,R(Regular)常規(guī),通過C和R的組合可以匹配出各種屏幕,如果不理解最直觀的可以查看StoryBoard中設(shè)置Autolayout時候在底部出現(xiàn)的w Any h Any通過鼠標(biāo)移動可以得出各種組合后能適配哪一種屏幕,這里就不再闡述。

  此圖可見,在iPad標(biāo)準(zhǔn)的屏幕比例種,width和height都是R,也就是說無論橫屏還是豎屏都是常規(guī)的組合即wR hR,然而在出現(xiàn)split和slide后狀態(tài)即發(fā)生的改變,在豎屏狀態(tài)下APP被分割后出現(xiàn)了wC hR,在橫屏狀態(tài)下,又出現(xiàn)了兩種組合分別是主APP70%從APP30%和主APP50%從APP50%,通過圖片得出在橫屏7:3中,主APP比例是wRhR,從APP比例是wChR,在5:5情況下主從APP都是wChR,那么就此知道了APP在slideView和splitView狀態(tài)下的各種高寬組合。

  總結(jié)一下APP在Slide和Split后的各種需要適配的尺寸是,100%常規(guī)狀態(tài),70%作為主APP的狀態(tài),50%作為split等分的狀態(tài),30%作為從APP出現(xiàn)時候的狀態(tài)。由于100%和70%都屬于wRhR,那么我們主要適配就分成三中情況 100%,50%,30%,如果APP界面主要以list為主或者比較簡單的布局,其實(shí)只要適當(dāng)調(diào)整Autolayout的offset值即可適配所有的情況,那么如果是比較復(fù)雜的界面或者需要滿足各種狀態(tài)下的顯示怎么辦呢,當(dāng)然是有解決的方案,以下主要以簡單代碼的例子進(jìn)行適配工作,主要理解原理和知道什么時候觸發(fā)顯示比例改變,還有種方法是通過Storyboard的SizeClass匹配上述所有狀況并且逐一調(diào)整差值,這種方式比較簡單用慣XIB的應(yīng)該很容易解決,缺點(diǎn)就是維護(hù)起來稍微不方便。

  首先,有個需求,在屏幕當(dāng)中放置一個紅色的UIView,在正常狀態(tài)下,左右兩邊距邊框100個像素,并且有個label顯示當(dāng)前的比例,當(dāng)出發(fā)split或者slide的時候,UIView的左右邊框調(diào)整為10個像素。具體的結(jié)果如下圖:

  

 

  

  上圖為正常的全屏,下圖為splitView之后的。

  首先代碼先在view內(nèi)增加一個紅色的UIView和一個label用于顯示當(dāng)前狀態(tài)。

 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.Center10         collectionStateLabel.textColor = UIColor.blackColor()11         self.view.addSubview(collectionStateLabel)   

  接著,開始分析實(shí)際情況,通過模擬器或者真機(jī)使用后就會發(fā)現(xiàn),在應(yīng)用程序啟動的時候就可能出現(xiàn)好幾種情況,紅色數(shù)字代表我的APP顯示比例

  場景1 如果我正在瀏覽照片,這時候突然想打開APP查看某樣?xùn)|西的時候那么這時候就會發(fā)生幾種情況。

  1 程序以SlideView啟動。                                  (10:3

  2 在通過SlideView啟動后又展開到了SplitView。                        (5:5

  3 在SplitView使用后我覺得不爽,太小了,再想進(jìn)一步展開又成為全屏。            (0:10

  場景2 如果我正在使用APP,這時候我想通過地圖查看某幢樓在哪里,這時候又會發(fā)生幾種情況。

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

  2 在查詢地圖的時候我還要使用回我的APP,這時候我的APP被激活,地圖同樣被激活          (7:3)

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

  從上總結(jié)出來,場景1我的APP是作為從APP存在,照片是主APP,場景2我的APP是作為主APP存在,地圖程序是從APP,其實(shí)這都不重要,最主要的得出結(jié)論就是在布局的時候一開始就必須考慮到針對不同的場景以適應(yīng)不同的布局需求。

  現(xiàn)在開始代碼布局,代碼布局使用了一個第三方的類庫以節(jié)省代碼量,Apple的API實(shí)在非常的繁瑣,在此使用SnapKit作為布局類庫 (https://github.com/SnapKit/SnapKit),OC版本(https://github.com/SnapKit/Masonry)

從場景1,2分析出在一開始就需要知道當(dāng)前的屏幕處在什么樣的比例之中,那么通過文章一開始分析的Apple文檔得出在slide和split下的比例都是wC hR也就是說寬是緊湊豎是標(biāo)準(zhǔn)。那么通過SizeClass的API就可以判斷出來。

     if self.traitCollection.verticalSizeClass == UIUserInterfaceSizeClass.Regular && self.traitCollection.horizontalSizeClass == UIUserInterfaceSizeClass.Compact{            //slide or split size slide和split狀態(tài)           }else{            //regular size 標(biāo)準(zhǔn)狀態(tài)        }

  通過 UITraitCollection 類可以獲取當(dāng)前屏幕處在什么樣子的比例當(dāng)中 ,這個類封裝了各種水平豎直方向等SizeClass的信息,通過實(shí)現(xiàn)了UITraitEnvironment接口的對象都可以拿到這個屬性,(UIViewController,UIView,UIWindow,UIScreen都實(shí)現(xiàn)了這個接口)。通過判斷屬性verticalSizeClass和horizontalSizeClass的各種組合即可很容易獲取到當(dāng)前屏幕水平垂直配比。

  至此,屏幕顯示比例判斷出來了,那么就根據(jù)需求和實(shí)際情況分別編寫不同比例下的適配代碼即可,這里根據(jù)需求在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)        }    }

  我們設(shè)置了兩個函數(shù)第一個函數(shù)適配regular的情況,第二個函數(shù)適配Split或Slide的情況,并且分別在label上標(biāo)注,這里使用了swift guard ... else {}來判斷如果約束不為空則更新約束,否則新增約束,關(guān)于snapkit用法具體請看GIT上說明,這里僅僅舉例。現(xiàn)在分別在初始化時候調(diào)用相應(yīng)的函數(shù)即可完成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)        }

  到了這一步已經(jīng)滿足了,APP從slide進(jìn)來時候的適配。但是,事情還沒那么簡單,通過場景1,2得出,在不滿足當(dāng)前大小的情況下可以從slide過渡到split,甚至從split過度到regular,那么就牽涉到動態(tài)更改布局了,好在Apple的API提供了一個函數(shù)來的到當(dāng)前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()        }    }

  這個函數(shù)類似于以前willRotateToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval)處理旋轉(zhuǎn)屏幕的邏輯一樣,當(dāng)sizeClass發(fā)生改變后立即會得到調(diào)用,那么在這個函數(shù)內(nèi)根據(jù)Apple文檔提供的slide和split的比例規(guī)則也非常容易對當(dāng)前布局進(jìn)行更新。

  至此,我們已經(jīng)完全滿足了需求和場景1和2的各種情況,綜上所述,只要知道sizeClass的各種比例組合就可以輕松應(yīng)付各種屏幕顯示發(fā)生改變的情況,再通過與Autolayout的配合,達(dá)到滿足各種尺寸及動態(tài)改變尺寸需求。最后,雖然蘋果引入的新的特性,看似復(fù)雜,其實(shí)還是使用老的技術(shù)來解決各種情況,sizeClass和autolayout配合猶如雙劍合壁,無懼任何尺寸大小的變更。

  題外話,如果習(xí)慣使用XIB的話用法還是和之前的一樣,只需要匹配各種Compact和Regular的組合并且設(shè)置好相應(yīng)的約束并且Install對應(yīng)的View也非常容易對付Slide和Split

  

只需要動動鼠標(biāo)修改下約束也很好的滿足實(shí)際的情況,只是storyboard的維護(hù)性和可讀性不是很友好,代碼可能會更容易做出修改維護(hù)和抽象,實(shí)際應(yīng)用我代碼使用的比較多點(diǎn)。


發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 上思县| 东阿县| 大兴区| 伊宁市| 永年县| 嘉祥县| 三门峡市| 洛隆县| 苏尼特左旗| 宁蒗| 怀柔区| 塔城市| 东宁县| 胶南市| 凉城县| 敖汉旗| 咸丰县| 兴山县| 台前县| 嵩明县| 天峻县| 富平县| 石阡县| 耒阳市| 陇南市| 平安县| 东阳市| 汶上县| 泰来县| 石家庄市| 昭平县| 扶沟县| 延津县| 泰州市| 福州市| 龙口市| 沙河市| 辽宁省| 竹北市| 邳州市| 汉阴县|