蘋果的產品iPad和iPhone都是支援自動旋轉的,因而我們寫的程式也要支援兩種視圖:縱向和橫向。
預設情況下,我們寫的程式都是縱向的,就像前邊的幾個例子中那樣。如果運行以前寫的程式,當把模擬器旋轉,你會發現很不友好,有的控制項看不見了。這個時候,自動旋轉就顯得很有必要了。
1、我們先不談如何?自動旋轉,先講講如何讓程式知道它支援哪幾種旋轉。
運行Xcode 4.2,建立一個Single View Application,程式名為RotateTest,其他設定如:
建立好工程後,開啟的第一個頁麵包含如下視圖:
我們可以在這裡設定程式支援哪種旋轉,只需選中那個按鈕。從可以看出,預設情況下,iPhone程式不支援倒過來的旋轉,因為如果視圖是倒過來的,而此時突然來電話,那麼會很不方便,因為頁面依然是倒過來的。但是,如果你建立了一個iPad程式,你回傳現四個按鈕都是選中的,即iPad程式預設支援所有旋轉。
注意,如果為程式建立了多個View Controller,那麼每個View Controller都要可以設定所支援的旋轉,不過,建立的View Controller設定的值必須是主View Controller的子集。
其實,我們修改中的按鈕,實質上修改的是我們程式的plist檔案,在這個工程中,是RotateTest-Info.plist檔案,如,展開這個檔案,最下面顯示的就是所支援的旋轉:
上面是設定支援選中的一種方法。我們也可以在代碼中設定所支援的旋轉。開啟ViewController.m,找到shouldAutorotateToInterfaceOrientation方法,完整代碼如下:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{ // Return YES for supported orientations return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);}
上面的代碼錶明,不支援倒轉(UIInterfaceOrientationPortraitUpsideDown)。
iOS中定義了四個表示方向的變數:
UIInterfaceOrientationPortraitUIInterfaceOrientationPortraitUpsideDownUIInterfaceOrientationLandscapeLeftUIInterfaceOrientationLandscapeRight
如果iOS設定旋轉了,程式就會調用這個方向,如果返回YES就旋轉視圖,否則的話就不旋轉。如果你建立了一個iPad程式,這個方法就是簡單的返回YES。
2、既然我們已經讓程式知道支援什麼旋轉了,下面講講如何?。
在iOS中有三種方法可以實現自動旋轉。
(1)最簡單的方法就是利用Xcode中的Size Inpector:
(2)在View所對應的ViewController.m中重寫willAnimateRotationToInterfaceOrientation方法,在這個方法中重新設定控制項的大小與位置。
(3)再建立一個視圖,這樣,我們有兩個視圖了,一個縱向,一個橫向。在這兩個視圖上設計好了之後,當旋轉時根據旋轉方向,調用相應的視圖。
3、以下是這三個方法的簡單使用。
3.1 使用Size Inpector實現自動旋轉:
① 單擊ViewController.xib,在開啟的視圖地區拖放兩個Button在上面,分別命名為“按鈕上”和“按鈕下”,頁面配置如:
圖中兩個按鈕在水平方向上是置中放置的。
② 運行程式,並將模擬器旋轉,對比一下旋轉前後的效果:
旋轉之後,“按鈕下”不見了。不過,“按鈕上”的座標和大小其實是沒變的。
我現在想實現旋轉之後兩個按鈕還是水平方向置中,並且還是一個在頂端、一個在底端。為實現這個,我要做以下工作:
③ 在View中選中“按鈕上”,開啟Size Inspector,把左邊的紅實線改成虛線:
④ 在View中選中“按鈕下”,開啟Size Inspector,把左邊和上邊的紅實線改成虛線,下邊的紅虛線改成實線:
外圍的紅實線表示距離不變,例如右中下方的紅實線就表示對應的控制項與下方的距離不變,而其他方向會自動調整。現在運行一下並旋轉模擬器,看看效果:
3.2 重寫willAnimateRotationToInterfaceOrientation方法,重新設定控制項的大小與位置
① 首先先給這兩個按鈕添加Outlet映射到ViewController.h,名稱分別是button_1和button_2:
② 在ViewController.m中的@end之前添加以下代碼:
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval) duration { if (UIInterfaceOrientationIsPortrait(toInterfaceOrientation)) { button_1.frame = CGRectMake(124, 20, 72, 37); button_2.frame = CGRectMake(124, 403, 72, 37); } else { button_1.frame = CGRectMake(20, 131, 72, 37); button_2.frame = CGRectMake(388, 131, 72, 37); }}
③ 運行,看看效果:
3.3 建立新視圖,旋轉時切換視圖:
① 我們先建立原始視圖的副本,但是還是在原來的ViewController中。單擊ViewController.xib,開啟IB,在左邊的三個表徵圖中選中View表徵圖,如果用的是Mac Book,那麼按住Control鍵,如果是虛擬機器,請按住Alt鍵。按住後按住滑鼠左鍵,往下拖,滑鼠會變成綠色的加號。注意新視圖跟原始圖是並列的,所以你要往正確的方向拖,然後鬆開滑鼠,這樣就建立了原來視圖的副本:
② 調整新視圖為橫向(Landscape):
選中新視圖,開啟Attribute Inspector,在Orientation中選擇Landscape:
③ 調整新視圖中的按鈕的位置,你可以按照自己的喜好設定,這裡設定成如下所示:
④ 下面,我們為這兩個View建立Outlet映射,注意是View,而不是View上的控制項。建立映射的方法都是一樣,兩個名稱分別是portrait和landscape:
⑤ 單擊ViewController.m,在@implementation那行代碼的下一行添加以下語句:
#define degreesToRadians(x) (M_PI*(x)/180.0)
⑥ 修改willAnimateRotationToInterfaceOrientation方法,如下:
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { if (toInterfaceOrientation == UIInterfaceOrientationPortrait) { self.view = self.portrait; self.view.transform = CGAffineTransformIdentity; self.view.transform = CGAffineTransformMakeRotation(degreesToRadians(0)); self.view.bounds = CGRectMake(0.0, 0.0, 320.0, 460.0); } else if(toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft) { self.view = self.landscape; self.view.transform = CGAffineTransformIdentity; self.view.transform = CGAffineTransformMakeRotation(degreesToRadians(-90)); self.view.bounds = CGRectMake(0.0, 0.0, 480.0, 300.0); } else if(toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) { self.view = self.landscape; self.view.transform = CGAffineTransformIdentity; self.view.transform = CGAffineTransformMakeRotation(degreesToRadians(90)); self.view.bounds = CGRectMake(0.0, 0.0, 480.0, 300.0); }}
⑦ 運行,查看效果:
4、小結
這次講了實現自動旋轉調整大小的三種方法,第一種只要點點滑鼠,很簡單,但不適合複雜的視圖;第二種要重新設定控制項的大小和位置,代碼量會比較大;第三種是建立兩種視圖,旋轉時調用不同的視圖,比較適合複雜的視圖。
原文出處:http://my.oschina.net/plumsoft/blog/47289