轉自:http://www.molotang.com/articles/1530.html
接着上篇寫的觸摸事件,這次借機會整理下iOS橫屏和豎屏的翻轉方向支持,即InterfaceOrientation相關的內容。
最近做一個頁面,最初並沒有太多考慮orientation的情況,當其嵌入到一個在iPad上使用橫屏(Landscape)的應用中,就會只顯示在屏幕的左面,而且貌似還沒顯示全,這個……很丑!發自內心地覺得這么做對不起蘋果的設計理念!對不起喬老爺子。。。
改!說到該就要了解蘋果開發中對iOS應用的橫屏(Landscape)和豎屏(Portrait)的支持情況。
0. 應用級別的配置
大家(特指有iOS開發經驗的人)應該都知道Xcode Project的工程配置General頁簽中有那么四個圖(或者4個checkbox),標識對四種interfaceOrientation的支持。分別為Portrait、PortraitUpsideDown、LandscapeLeft和LandscapeRight。
對應的,在Xcode Project工程配置的Info頁,實際上就是Info.plist中,有對4種Orientation的記錄項。
這兩者是一樣的。
1. Window級別的控制
在iOS6.0之后,UIApplicationDelegate中多了一個方法聲明:
1
|
- (
NSUInteger
)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
|
就是對於特定的application和特定的window,我們需要支持哪些interfaceOrientation,這是可以通過實現這個方法定制的。
返回值是一個無符號整數,實際上是可以使用定義好的枚舉值:
1
2
3
4
5
6
7
8
9
|
typedef
NS_OPTIONS
(
NSUInteger
, UIInterfaceOrientationMask) {
UIInterfaceOrientationMaskPortrait = (1 << UIInterfaceOrientationPortrait),
UIInterfaceOrientationMaskLandscapeLeft = (1 << UIInterfaceOrientationLandscapeLeft),
UIInterfaceOrientationMaskLandscapeRight = (1 << UIInterfaceOrientationLandscapeRight),
UIInterfaceOrientationMaskPortraitUpsideDown = (1 << UIInterfaceOrientationPortraitUpsideDown),
UIInterfaceOrientationMaskLandscape = (UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight),
UIInterfaceOrientationMaskAll = (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskPortraitUpsideDown),
UIInterfaceOrientationMaskAllButUpsideDown = (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight),
};
|
對於UIApplicationDelegate的這個方法聲明,大多數情況下application就是當前的application,而window通常也只有一個。所以基本上通過window對橫屏豎屏interfaceOrientation的控制相當於全局的。
2. Controller層面的控制
老版本的iOS有這樣一個方法:
1
|
- (
BOOL
)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
NS_DEPRECATED_IOS
(2_0, 6_0);
|
即定制是否可以旋轉到特定的interfaceOrientation。
而在iOS6之后,推出了2個新的方法來完成這個任務:
1
2
|
- (
BOOL
)shouldAutorotate
NS_AVAILABLE_IOS
(6_0);
- (
NSUInteger
)supportedInterfaceOrientations
NS_AVAILABLE_IOS
(6_0);
|
可以看得出來,兩個和在一起就是原來任務的完成過程。其中,大概的判斷方式是,先執行前者,判斷是否可以旋轉,如果為YES,則根據是否支持特定的interfaceOrientation再做決斷。
3. 使得特定ViewController堅持特定的interfaceOrientation
iOS6之后還提供了這樣一個方法,可以讓你的Controller倔強第堅持某個特定的interfaceOrientation:
1
|
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
NS_AVAILABLE_IOS
(6_0);
|
這就叫堅持,呵呵!
當然,這里使用的是另外一套枚舉量,可以去UIApplication.h中查看定義。
4. 當前屏幕方向interfaceOrientation的獲取
有3種方式可以獲取到“當前interfaceOrientation”:
- controller.interfaceOrientation,獲取特定controller的方向
- [[UIApplication sharedApplication] statusBarOrientation] 獲取狀態條相關的方向
- [[UIDevice currentDevice] orientation] 獲取當前設備的方向
具體區別,可參見StackOverflow的問答:
http://stackoverflow.com/questions/7968451/different-ways-of-getting-current-interface-orientation
5. 容器Controller的支持
上面把interfaceOrientation方向的獲取和支持配置都說了,看起來沒什么問題了。有沒有什么特殊情況?
當你使用TabbarController和NavigationController按照如上做法使用的時候就會有些頭疼。
辦法不是沒有,比較通俗的一種就是——繼承實現。
(補充:iOS7之后有delegate可以對此進行控制)
關於iOS interface orientation屏幕方向的內容就整理到此,歡迎各位看官發言。