使用 Interface Builder 兼容 iOS6 和iOS7

jopen 10年前發布 | 36K 次閱讀 iOS6 iOS開發 移動開發

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

使用 Interface Builder 兼容 iOS6 和iOS7
此圖為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 兼容 iOS6 和iOS7

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中的錯位

使用 Interface Builder 兼容 iOS6 和iOS7            使用 Interface Builder 兼容 iOS6 和iOS7

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 兼容 iOS6 和iOS7            使用 Interface Builder 兼容 iOS6 和iOS7

Interface builder 設置                               Interface Builder設置

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

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

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

使用 Interface Builder 兼容 iOS6 和iOS7

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

使用 Interface Builder 兼容 iOS6 和iOS7

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

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

使用 Interface Builder 兼容 iOS6 和iOS7                     使用 Interface Builder 兼容 iOS6 和iOS7

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

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

使用 Interface Builder 兼容 iOS6 和iOS7

Interface Builder中UINavigationBar 的半透明設

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

使用 Interface Builder 兼容 iOS6 和iOS7

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上或者更高的版本。

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

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

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!