螢幕自動旋轉的機制在 iOS6 中有了重大的改變,由於沒時間研究(另外一種說法就是懶~哈哈),就讓舊程式碼一直將究著使用,直到發現情況不妙了,只好還是花時間來找答案。
在 iOS5 之前的寫法如下:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
只要覆寫 UIViewController 的處理自動旋轉的方法,回傳想要的螢幕方向即可,可以用 OR ( || )來增加想要的方向,如下:
return (interfaceOrientation == UIInterfaceOrientationPortrait) || (interfaceOrientation == UIInterfaceOrientationLandscapeLeft) || (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
在 iOS5 之前的做法是必須在每一個 UIViewController 中去覆寫該方法來指示要接受的螢幕方向。當然在 *-info.plist 檔中也要設定可以旋轉的方向。我覺得做起來簡單,只是麻煩了點,每個頁面都要去加那個判斷式。這些動作在 iOS6 上完全無效,因為 iOS6 已經把該方法捨棄了,所以如果你什麼都不做,在 iOS6 上的執行結果就是你的 *-info.plist 中指定了可以轉什麼方向,就什麼方向都能轉。對於我全部都是直式,但只有某一個頁面可以轉橫的需求來說,整個 App 用起來的感覺爛透了。
最後呢,就是我找了半天終於找到正確的解決方法,我還沒能體會這個方式的好壞,但知道怎麼解決後,還滿容易的,感覺是在使用旋轉的概念上的簡化,讓整個概念更直覺。
整個設定流程如下:
- 設定 *-info.plist 中的 Supported interface orientations
- 建立自己的 UINavigationController
- 在自己 UINavigationController 中覆寫兩個方法:(BOOL)shouldAutorotate 及 (NSUInteger)supportedInterfaceOrientations
- 把 UINavigationController 加為頂層的 view
- 在每個頁面 UIViewController 中覆寫兩個方法:(BOOL)shouldAutorotate 及 (NSUInteger)supportedInterfaceOrientations
如果你的 App 的旋轉是所有頁面都相同,那步驟 3 即可將完成這些設定,不需要再做步驟 5 ,這應該是最大的好處,不需要每個頁面都去設定旋轉。但若某些頁面可以轉有些不行,那就和之前 iOS5 時一樣,每個頁面都要覆寫那兩個方法,只是那兩個方法的概念上不一樣了。之前是問你可以轉什麼方向,現在分成兩個問題,一個問可不可以自動旋轉,你只要回答可以或不可以;另一個則問你螢幕支援的方向,你只要回答這個頁面支援的方向就好。
流程解說
1.設定 *-info.plist 中的 Supported interface orientations
兩種做法,第一種直接去修改 plist 檔,太麻煩了!所以用第二種,在 Xcode 中選擇專案 -> TARGETS ->Summary頁籤,然後點選你想要支援的螢幕方向。如下圖:2. 建立自己的 UINavigationController
新增一個 Objective-C class 檔案,繼承 UINavigationController,然後什麼都不用做,結束這回合(疑?)。3. 覆寫方法
打開你的 NavigationController (.m) 貼上以下程式碼:- (BOOL)shouldAutorotate
{
return self.topViewController.shouldAutorotate;
}
- (NSUInteger)supportedInterfaceOrientations
{
return self.topViewController.supportedInterfaceOrientations;
}
每個頁面都會透過 NavigationController 的這兩個方法告訴最上層的 ViewController 螢幕可不可以自動旋轉及支援的方向。
4. 把 UINavigationController 加為頂層的 view
這部份會因你使用 xib 或 storyboard 而有所不同,若用 xib 要修改 delegate 中的 didFinishLaunchingWithOptions 方法,如下:- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// set initial view
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
navigationController = [[CustomNavigationController alloc]
initWithRootViewController:viewController]; // iOS 6 autorotation fix
[navigationController setNavigationBarHidden:YES animated:NO];
self.window = [[UIWindow alloc]
initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window setRootViewController:navigationController]; // iOS 6 autorotation fix
//[self.window addSubview:navigationController.view];
[self.window makeKeyAndVisible];
return YES;
}
這部份我沒試,所以你要自己試看看。我用 storyboard ,做法簡單了些,完全不用加程式碼,如果你也用 storyboard 而加上以上的程式碼,會出錯。因為我的 storyboard 中已經有一個 Navigation Controller (若沒有請自行從元件庫中拉一個出來),選擇它,在 Identity Inspector 面版中修改 class 為你自定的 NavigationController ,如下圖:
5. 在每個頁面 UIViewController 中覆寫兩個方法
程式碼如下:- (BOOL)shouldAutorotate
{
return NO;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
第一個方法就是該頁面可不可以自動旋轉,第二個則是支援的螢幕方向。基本上只要設定第一個方法,該螢幕就不會旋轉了,那幹嘛要設定第二個呢?我遇到的狀況是,我的頁面都是直的,當我從目前頁面進入下一個面頁時,若第二個頁面可以旋轉,並且使用者在轉成橫的方向時按下導覽列上的返回按鈕,回到的第一頁也會是轉成橫的!!而且怎麼都轉不回來,因為我們的第一個方法回答說 "不能轉",所以現在你知道為什麼要設定第二個方法了,那就是說「螢幕不能轉,而且只能直著看」,這樣就不會因為其他頁面的方向而影響了該頁面的方向。
總結
還沒去探究為什麼 iOS6 的旋轉機制要改成這樣,因為你無論如何都要建立一個 Navigation Controller ,那不需要的人怎麼辦呢?只好建立之後設為隱藏,還不太明白這個做法。新的螢幕方向常數帶有 ***Mask*** 字樣,這點要注意。原本一個只要覆寫一個方法,現在則要覆寫兩個方法,比較囉唆一點,但是至少比較清楚明白該方法的用途。參考資料
- iOS 6 Autorotation Problems and Help
- iOS 6 Rotation Solution
- MPMoviePlayerController rotating in full screen while the parent View Controller only supports portrait orientation
本文網址:http://blog.tonycube.com/2013/05/ios-ios6-screen-autorotate.html
由 Tony Blog 撰寫,請勿全文複製,轉載時請註明出處及連結,謝謝 😀
由 Tony Blog 撰寫,請勿全文複製,轉載時請註明出處及連結,謝謝 😀
我要留言
留言小提醒:
1.回覆時間通常在晚上,如果太忙可能要等幾天。
2.請先瀏覽一下其他人的留言,也許有人問過同樣的問題。
3.程式碼請先將它編碼後再貼上。(線上編碼:http://bit.ly/1DL6yog)
4.文字請加上標點符號及斷行,難以閱讀者恕難回覆。
5.感謝您的留言,您的問題也可能幫助到其他有相同問題的人。