使用 Interface Builder 兼容 iOS6 和iOS7

使用 Interface Builder 兼容 iOS6 和iOS7

當你在更新你的App到iOS 7的平臺時遇到最大的挑戰之一就是確保不要遺忘那些還在使用iOS 6平臺的用戶,在此我們提供一些建議使你的App應用在iOS 6和iOS 7上同時保留視覺吸引力和技術功能.

 
此圖爲Interface Builder中頂部和底部佈局指南

設置正確的Interface Builder Storyboard 或者正確設置XIBs文件,對於iOS 6 和iOS7的開發大有幫助,使得開發更加容易。我們的第一個建議是爲全部的UIViewController創建Storyboard, UIViewControl是合成的或者是跨越整個屏幕高度的控制試圖(Control Views).如果你正在做的項目是使用XIBs文件開發的,而沒有使用Storyboards,那麼Storyboards可以儘可能的簡化爲帶有視圖容器(View Container)的“UIViewController",將來你可以從NIB文件加載。我們這樣建議的主要原因是這樣操作你可以獲得訪問在Interface Builder中頂部和底部佈局指南的權限。

Interface Builder中”View as“ 配置,這個設置是每個文件(NIB 或者Storyboard)的基礎設置。

另外,我們還建議您把所有的XIBs和Storyboard中的 View as 設置爲 iOS 7 and Later,這種設置方式將更加容易降低未來的iOS 6的支持,此外,如果您沒有使用自動佈局,那麼就會更加容易更加直觀的使用iOS 6/7 Delta 。

調整狀態欄

在iOS 7中狀態欄後面的區域變爲有用的屏幕空間。因此iOS 7的窗口比iOS6要高出20個點,這就導致了在iOS 7中屏幕頂部的內容顯示在狀態欄的下面,調整View可以使用或者避免iOS 7中額外的空間導致在iOS 6中的錯位

            

iOS 7-內容顯示在狀態欄下面             iOS 6 內容顯示在屏幕外面

如果你的項目沒有使用自動佈局(Auto Layout),那麼可以通過Spring,Struts以及iOS 6/7 Deltas來解決因爲iOS 6/7差異導致的狀態欄的問題。爲了避免內容顯示在狀態欄下面,僅需簡單的把內容移到下面,不管怎樣都需要移動幾個點來得到狀態欄下面的內容。然而,這也同時會導致iOS 6的內容往下移,這顯然不是我們所期望的,因爲這個內容在iOS6中原本不在狀態欄的下方。爲了解決這個問題,我們可以通過設置iOS 6/7 Delta來解決,設置一個負值在Y Delta等同於在iOS中向下移動幾個點。 比方說,我們在iOS 7中向下移動內容20點,那麼我們需要把Y Delta設置爲 -20。爲了把靠近屏幕底部的內容放置到屏幕底部相對位置,使用正確的Sping,Struts配置會更加容易更加可靠,而不是使用iOS 6/7 Deltas。同理而言,我們可以使用相似的方法調整需要跨越整個屏幕高度的視圖(Views)。可以通過在Storyboard 或XIB中調整高度或者起始原點來獲得類似iOS 7的大小和位置,以及在Delta中使用Y值或高度設置,結合Sping 和Struts來解決iOS 6中的大小和位置的問題。

以下,提供了簡單的範例,使用兩個圖片Views(一個在屏幕頂部,一個在屏幕底部)

            

Interface builder 設置                               Interface Builder設置

持續保持頂部的UIImageView在狀態欄的下方   防止UIImageView離開屏幕底部 

如前所述,假設你正在使用Storyboard,簡單的使用由Interface Builder提供的頂部和底部佈局的嚮導,那麼自動佈局可以更加簡單的解決由狀態欄差異造成的問題。如果你設置你的頂部和底部的NSLayoutConstraint 是相對於頂部和底部的佈局嚮導(而非root view的頂部和底部),那麼在iOS 6和iOS 7中,iOS將自動的做出必要的調整來使得所有信息都顯示在屏幕上並且露出狀態欄。如果你不能使用Storyboards,你將可能需要通過代碼來訪問頂部和底部的佈局嚮導。

下面是和以前一樣的例子,但是不同於先前,下面是通過使用自動佈局和NSLayoutConstraint 中設置頂部和底部相對性來解決這個問題

(博主ps:xcode6.1 點中uiimageview  然後ctrl-drag時要先把uiimageview的y軸設置大於1,不然如下圖,其他版本未測試,

正確的操作後應該是下圖,是image.Top-》Top Layout Guide.Bottom,反之也對)

相對的在UIImageView的頂部約束(constraint)中設定 Top Layout Guide

相對的在UIImageView的底部約束(constraint)中設定 Bottom Layout Guide

現在,無論使用Struts,Spring還是iOS 6/7 Dletas又或者使用自動佈局和頂部底部佈局嚮導,所有信息都可以被正確的在iOS 6 和iOS 7中顯示。

                     

在Interface Builder 調整後的iOS 7界面      在Interface Builder調整後的iOS 6界面

 使用iOS 7半透明的UINavigationBar調整UINavigationController


Interface Builder中UINavigationBar 的半透明設

當用Interface Builder同時支持iOS 6和iOS 7中遇到的最常見的挑戰是爲iOS 7設置UINavigationControllerUINavigationBar爲半透明,將UINavigationBar設置爲半透明會對你的視圖(Views)有非常大的影響,並且需要你做出一些改變。

Interface Build在Extend Edges(邊界擴展)中的設置

如果在一個UIViewController裏把Extend Edges設置爲Under Top Bars,你將發現在Interface Builder中切換Translucent(半透明)設置將導致視圖上下移動.在iOS 7中將UINavigationBar設置爲半透明將導致視圖在UINavigationBar的下面向上移動,而由於iOS 6中不支持設置半透明的UINavigationBar,這個設置在iOS 6中沒有任何變化;視圖始終保持在UINavigationBar下面,你可以留意到在iOS 6中Black Translucent UIBarStyle被標註爲不適用(Deprecated),而其他的UIBarStyle可在iOS 6中創建不透明的UINavigationBar.這個原因導致的情況和我們前面章節討論的關於新的狀態欄的問題非常相似,也就是我們提到的在iOS 7中的可用的屏幕空間高於iOS 6中的情況。

絕大部分由於調整UINavigationBar半透明度所導致的問題可以通過我們前面介紹的方法來解決,然而不論怎樣,如果有一個或者多個在UINavigationBar下面向上移動的視圖,額外的步驟也就是UIScrollView(或者UIScrollView的子類,比方說UITableView)都是必要的. 如果你使用Storyboard來擴建在UINavigationBar下面向上移動的UIScrollView(或者子類),那麼內容插圖將被自動設置。自動調整的內容插圖爲了確保內容在UIScrollView內,將在UINavigationBar下面設置初始的偏移量,因而對用戶來說會立即可見。不管怎樣,如果使用不太直接的方式操作在UINavigationBar下面向上移動的UIScrollView(或者子類),這裏不太直接的方法比如說通過XIB創建,之後加載到容器視圖(container view),那麼你就需要自己去設置內容插圖了。

在Interface Builder中也是可以設置內容插圖的,但是針對這種情況,我建議在代碼中做這個設置,我們有很多的理由這樣建議您,首先,我們只想在iOS 7中而非iOS 6中設置插圖,而Interface Builder是不可能實現這樣的設置的,其次,我們只想在運行iOS 7時設置內容插圖,我們可以使用Top Layout Guide(頂部佈局嚮導)來幫助我們設置內容插圖(即便你的Storyboard或XIB沒有使用自動佈局)。 下面是一個示例來告訴如何通過代碼完成這個設置,在這裏示例中,我使用了一個UITableView而沒使用UIScrollView,因爲這是更加普遍的情況。 在訪問UIViewController的屬性topLayoutGuide之前,必須確保你在iOS 7上或者更高的版本。

1 if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0f) {
2     CGFloat topInset = self.tableView.contentInset.top + [self.topLayoutGuide length];
3     CGFloat leftInset = self.tableView.contentInset.left;
4     CGFloat bottomInset = self.tableView.contentInset.bottom;
5     CGFloat rightInset = self.tableView.contentInset.right;
6   
7     self.tableView.contentInset = UIEdgeInsetsMake(topInset, leftInset, bottomInset, rightInset);
8 }

特別的指出,因爲每個App都有唯一的構造,讓你的App在視覺吸引力以及全部功能都能完美的運行在iOS 6和iOS 7上是一件非常有挑戰的工作。對於同時支持iOS 6和iOS 7,處理兼容性的問題,在這裏做出預測以及覆蓋所有可能的情況,這幾乎是不可能做到的事情,因此希望通過這篇文章幫助大家處理一些常見的情況,並且幫助你在正確的方向上以便更好的處理罕見或複雜的狀況

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章