iOS屏幕旋轉學習筆記
iOS開發中使用屏幕旋轉功能的相關方法
1、基本知識點解讀
了解屏幕旋轉首先需要區分兩種 orientation
1.1、device orientation
設備的物理方向
1.2、interface orientation
界面顯示的方向
iOS提供了在設備旋轉時,界面顯示發生相應適配的能力,以達到方便用戶使用并提供最佳顯示效果的目的。
開發者需要指定應用支持的顯示方向
,并對界面顯示做出對應的適配。
由于界面適配的工作量相當大,目前國內的應用大都只支持默認的豎屏方向。
2、屏幕旋轉的流程
加速計是整個IOS屏幕旋轉的基礎。
依賴加速計,設備才可以判斷出當前的設備方向。
當加速計檢測到方向變化的時候,會發出
UIDeviceOrientationDidChangeNotification 通知。
屏幕旋轉的流程如下:
1>、加速計來識別設備的旋轉方向。
發送 UIDeviceOrientationDidChangeNotification 設備旋轉的通知。
2>、app 接收到旋轉事件(通知事件)。
2>、app 通過AppDelegate通知當前程序的KeyWindow。
3>、Window 會知會它的 rootViewController,判斷該view controller所支持的旋轉方向,完成旋轉。
4>、如果存在 modal 的view controller的話,系統則會根據 modal 的view controller,來判斷是否要進行旋轉。
UIDevice 對象可以選擇性的(是否)接收
UIDeviceOrientationDidChangeNotification 通知。
// 是否已經開啟了設備方向改變的通知
@property(nonatomic,readonly,getter=isGeneratingDeviceOrientationNotifications)
BOOL generatesDeviceOrientationNotifications
__TVOS_PROHIBITED;
// 開啟接收接收 UIDeviceOrientationDidChangeNotification 通知
- (void)beginGeneratingDeviceOrientationNotifications
__TVOS_PROHIBITED; // nestable
// 結束接收接收 UIDeviceOrientationDidChangeNotification 通知
- (void)endGeneratingDeviceOrientationNotifications__TVOS_PROHIBITED;
在 app 代理里面結束接收 設備旋轉的通知事件, 后續的屏幕旋轉都會失效
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 結束接收接收 UIDeviceOrientationDidChangeNotification 通知
[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
return YES;
}
3、如何決定interface orientation (界面方向)
3.1、全局控制
Info.plist文件中,有一個Supported interface orientations,可以配置整個應用的屏幕方向,此處為 全局控制
。
3.2、UIWindow
iOS6的UIApplicationDelegate提供了下述方法,能夠指定 UIWindow 中的界面的屏幕方向:
// 該方法默認值為 Info.plist 中配置的 Supported interface orientations 項的值。
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window NS_AVAILABLE_IOS(6_0);
iOS中通常只有一個 window,所以此處的控制也可以視為全局控制。
3.3、controller (單個界面控制)
只有以下兩種情況:
當前 controller 是 window 的 rootViewController
當前 controller 是 modal 模式的時(controller 為 modal 顯示的控制器),orientations相關方法才會起作用(才會被調用),當前controller及其所有的childViewController都在此作用范圍內。
3.4、最終支持的屏幕方向
一個界面最后支持的屏幕方向,是取 (全局控制 ∩ UIWindow 中的界面控制 ∩ 單個界面控制)
的交集。
如果全局控制支持所有屏幕方向,UIWindow 中的界面控制支持橫屏,當個界面中只是支持橫屏向右,那么最后界面只會以橫屏向右顯示,并且不支持旋轉到其他的方向。
如果最終的交集為空,在iOS6以后會拋出
UIApplicationInvalidInterfaceOrientationException
崩潰異常。
4、API 使用講解
4.1**UIViewController Rotation 的 api **
// To make it more convenient for applications to adopt rotation, a view controller may implement the below methods. Your UIWindow's frame should use [UIScreen mainScreen].bounds as its frame.
// 為了讓控制器更加方便的旋轉,視圖控制器可以實現下面這些方法。你的 UIWindow 的 frame 將要使用 UIScreen mainScreen].bounds 作為他的 frame。
@interface UIViewController (UIViewControllerRotation)
// call this method when your return value from shouldAutorotateToInterfaceOrientation: changes
// if the current interface orientation does not match the current device orientation, a rotation may occur provided all relevant view controllers now return YES from shouldAutorotateToInterfaceOrientation:
// 試著去旋轉到界面的方向
// 使用場景是 interface orientation和device orientation 不一致,
// 希望通過重新指定 interface orientation 的值,立即實現二者一致;
// 如果這時只是更改了支持的 interface orientation 的值,沒有調用attemptRotationToDeviceOrientation,那么下次 device orientation 變化的時候才會實現二者一致,關鍵點在于能不能立即實現。
+ (void)attemptRotationToDeviceOrientation NS_AVAILABLE_IOS(5_0) __TVOS_PROHIBITED;
// Applications should use supportedInterfaceOrientations and/or shouldAutorotate..
// 應用將要使用界面支持的方向,或者將要自動旋轉 (在 iOS6 以后被禁用, 要兼容 iOS 6 還是需要實現這個方法)
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation NS_DEPRECATED_IOS(2_0, 6_0) __TVOS_PROHIBITED;
// New Autorotation support.
// 新的自動旋轉的支持 (上面的方法被下面兩個方法替代)
// 將要自動旋轉 (在 iOS6 開始啟用)返回 yes 為支持旋轉,no 為不支持旋轉
- (BOOL)shouldAutorotate NS_AVAILABLE_IOS(6_0) __TVOS_PROHIBITED;
// 支持的界面方向
- (UIInterfaceOrientationMask)supportedInterfaceOrientations NS_AVAILABLE_IOS(6_0) __TVOS_PROHIBITED;
// Returns interface orientation masks.
// 返回現在正在顯示的用戶界面方向
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation NS_AVAILABLE_IOS(6_0) __TVOS_PROHIBITED;
// The rotating header and footer views will slide out during the rotation and back in once it has completed.
- (nullable UIView *)rotatingHeaderView NS_DEPRECATED_IOS(2_0,8_0, "Header views are animated along with the rest of the view hierarchy") __TVOS_PROHIBITED; // Must be in the view hierarchy. Default returns nil.
- (nullable UIView *)rotatingFooterView NS_DEPRECATED_IOS(2_0,8_0, "Footer views are animated along with the rest of the view hierarchy") __TVOS_PROHIBITED; // Must be in the view hierarchy. Default returns nil.
// 獲取用戶界面的方向 (方法在 iOS8 被禁用,方法是只讀的)
@property(nonatomic,readonly) UIInterfaceOrientation interfaceOrientation NS_DEPRECATED_IOS(2_0,8_0) __TVOS_PROHIBITED;
// Notifies when rotation begins, reaches halfway point and ends.
// 當旋轉開始,到達一半,結束的時候,將通過下列方法得到通知。
// 將要旋轉到用戶界面
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration NS_DEPRECATED_IOS(2_0,8_0, "Implement viewWillTransitionToSize:withTransitionCoordinator: instead") __TVOS_PROHIBITED;
// 已經從某個用戶界面開始旋轉
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation NS_DEPRECATED_IOS(2_0,8_0) __TVOS_PROHIBITED;
// 將要動畫旋轉到用戶界面
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration NS_DEPRECATED_IOS(3_0,8_0, "Implement viewWillTransitionToSize:withTransitionCoordinator: instead") __TVOS_PROHIBITED;
// 界面切換到一半的控制
- (void)willAnimateFirstHalfOfRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration NS_DEPRECATED_IOS(2_0, 5_0) __TVOS_PROHIBITED;
- (void)didAnimateFirstHalfOfRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation NS_DEPRECATED_IOS(2_0, 5_0) __TVOS_PROHIBITED; // The rotating header and footer views are offscreen.
- (void)willAnimateSecondHalfOfRotationFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation duration:(NSTimeInterval)duration NS_DEPRECATED_IOS(2_0, 5_0) __TVOS_PROHIBITED; // A this point, our view orientation is set to the new orientation.
@end
4.2 api 的說明
// Applications should use supportedInterfaceOrientations and/or shouldAutorotate..
// 應用將要使用界面支持的方向,或者將要自動旋轉 (在 iOS6 以后被禁用, 要兼容 iOS 6 還是需要實現這個方法)
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation NS_DEPRECATED_IOS(2_0, 6_0) __TVOS_PROHIBITED;
這一個接口被下面兩個接口替代 (在 iOS6 以后)
// 將要自動旋轉 (在 iOS6 開始啟用)返回 yes 為支持旋轉,no 為不支持旋轉
- (BOOL)shouldAutorotate NS_AVAILABLE_IOS(6_0) __TVOS_PROHIBITED;
// 支持的界面方向 (在 iOS6 開始啟用)
- (UIInterfaceOrientationMask)supportedInterfaceOrientations NS_AVAILABLE_IOS(6_0) __TVOS_PROHIBITED;
如果需要兼容 iOS6 之前的系統還是需要實現老的接口,要不 app 只能支持豎屏不能旋轉
4.3 api 接口的簡單使用 (iOS 6 之后)
當只需要鎖定屏幕的旋轉不需要設置屏幕的旋轉方向 ( 方向固定是豎直)
// 是否支持屏幕旋轉
-(BOOL)shouldAutorotate {
return NO;
}
開啟屏幕旋轉并設置屏幕旋轉支持的方向
// 是否支持屏幕旋轉 (返回 NO 后面倆方法不調用,后面只支持豎直方向)
-(BOOL)shouldAutorotate {
return NO;
}
// 支持屏幕旋轉的方向
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
// 通過設置返回的枚舉值來改變屏幕旋轉支持的方向
//(iPad上的默認返回值是UIInterfaceOrientationMaskAll,
// iPhone上的默認返回值是UIInterfaceOrientationMaskAllButUpsideDown)
return UIInterfaceOrientationMaskAll;
}
// Returns interface orientation masks. (返回最優先顯示的屏幕方向)
// 同時支持Portrait和Landscape方向,但想優先顯示Landscape方向,那軟件啟動的時候就會先顯示Landscape,在手機切換旋轉方向的時候仍然可以在Portrait和Landscape之間切換;
// 返回現在正在顯示的用戶界面方向
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
};
** 屏幕旋轉設置注意點:**
在iOS 4 and 5,都是由具體的view controller來決定對應的view的orientation設置。
而在iOS 6,則是由 top-most controller來決定 view 的 orientation 設置。
舉個例子:
你的app的rootViewController是navigation controller "nav", 在”nav"里的stack依次是:main view -> sub view > sub sub view,而main view里有一個button會present modal view "modal view".
那么for ios 4 and 5,在ipad里,如果你要上述view都僅支持橫屏orientation,你需要在上面的main view, sub view, sub sub view, model view里都添加:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation==UIInterfaceOrientationLandscapeRight);
}
而對于iOS6, 由于是由 top-most controller 來設置 orientation,因此你在main view, sub view, sub sub view里添加下面的代碼是沒有任何效果的,
而應該是在nav controller里添加下列代碼。
而modal view則不是在nav container里,因此你也需要在 modal view controller 里也添加下列代碼。
- (BOOL)shouldAutorotate {
return YES;
}
-(NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscape;
}
** 注意:**
你需要自定義一個UINavigationController的子類for "nav controller",這樣才可以添加上述代碼。和navigation controller類似,tab controller里的各個view的orientation設置應該放在tab controller里
** api 說明:**
** attemptRotationToDeviceOrientation 使用說明:**
// call this method when your return value from shouldAutorotateToInterfaceOrientation: changes
// if the current interface orientation does not match the current device orientation, a rotation may occur provided all relevant view controllers now return YES from shouldAutorotateToInterfaceOrientation:
// 該方法的使用場景是 interface orientation和device orientation 不一致,但希望通過重新指定 interface orientation 的值,立即實現二者一致;
// 如果這時只是更改了支持的 interface orientation 的值,沒有調用attemptRotationToDeviceOrientation,那么下次 device orientation 變化的時候才會實現二者一致,關鍵點在于能不能立即實現。
+ (void)attemptRotationToDeviceOrientation {
// code
}
舉個例子:
假設當前的 interface orientation 只支持 Portrait。
如果 device orientation 變成 Landscape,那么 interface orientation 仍然顯示 Portrait;
如果這時我們希望 interface orientation 也變成和 device orientation 一致的 Landscape,
以iOS 6 為例,需要先將 supportedInterfaceOrientations 的返回值改成Landscape,然后調用 attemptRotationToDeviceOrientation方法,系統會重新詢問支持的 interface orientation,已達到立即更改當前 interface orientation 的目的。
** supportedInterfaceOrientations 使用說明: **
此方法返回當前viewController 支持的方向. 但是, 只有兩種情況下此方法才會生效:
1、當前viewController是window的rootViewController.
2、當前viewController是modal模式的. 即, 此viewController是被調用
presentModalViewController 而顯示出來的.
在以上兩種情況中,UIViewController.supportedInterfaceOrientations 方法會作用于前viewController和所有childViewController. 以上兩種情況之外, UIKit并不會理會你的supportedInterfaceOrientations 方法.
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft;
}
如果某個viewController實現了以上方法. 則, 此viewController就支持豎方向和左旋轉方向. 此viewController的所有childViewController也同時支持這兩個方向, 不多不少.
** preferredInterfaceOrientationForPresentation 使用說明: **
此方法也僅有在當前viewController是rootViewController或者是modal模式時才生效.
** shouldAutorotate 使用說明:**
用于設置當前viewController是否支持自動旋轉. 如果,你需要viewController
暫停自動旋轉一小會兒. 那么可以通過這個方法來實現.
同樣的, 此方法也僅有在當前viewController是rootViewController或者是modal模式時才生效.
5、實現屏幕的旋轉
5.1、在 iOS6 之后存在豎屏幕固定和需要進行旋轉的界面的需求配置:
for ios6的top-most controller決定orientation設置,導致這樣一個問題:
在 top-most controller里的views無法擁有不相同的orientation設置。
例如:for iphone, 在nav controller里,你有main view, sub view and sub sub view,前2個都只能打豎,而sub sub view是用來播放video,可以打橫打豎。
那么在ios 4 and 5里可以通過在main view and sub view的shouldAutorotateToInterfaceOrientation里設置只能打豎,而在sub sub view的shouldAutorotateToInterfaceOrientation設置打豎打橫即可。
而在ios 6里則無法實現這種效果,因為在main view, sub view and sub sub view的orientation設置是無效的,只能夠在nav controller里設置。那么你可能想著用下列代碼在nav controller里控制哪個view打豎,哪個view打橫:
-(NSUInteger)supportedInterfaceOrientations{
if([[self topViewController] isKindOfClass:[SubSubView class]])
return UIInterfaceOrientationMaskAllButUpsideDown;
else
return UIInterfaceOrientationMaskPortrait;
}
是的,這樣可以使得在main view and sub view里無法打橫,而sub sub view橫豎都行。但問題來了,如果在sub sub view時打橫,然后back to sub view,那么sub view是打橫顯示的!
目前想到的解決方法只能是把sub sub view脫離nav controller,以modal view方式來顯示。
這樣就可以在modal view里設置打橫打豎,而在nav controller里設置只打豎。
說了那么多,其實如果你的app的所有view的orientation的設置是統一的,那么你可以簡單的在plist file里設置即可,不用添加上面的代碼。而如果你添加了上面的代碼,就會覆蓋plist里orientation的設置。
in iOS 6, 當view controller present時,
不會call willRotateToInterfaceOrientation:duration:,
willAnimateRotationToInterfaceOrientation:duration:,
and didRotateFromInterfaceOrientation: methods,只有在發生rotate的時候才會call。
5.2、強制旋轉
iOS兩個強制旋轉屏幕的方法
有時候, 需要不隨系統旋轉, 而是強制旋轉到某一個角度. 最典型的場景就是視頻播放器, 當點擊了全屏按鈕的時候, 需要橫過來顯示.
對于IOS5及以前的版本, 可以用下面的方法:
if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) {
SEL selector = NSSelectorFromString(@"setOrientation:");
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDevice instanceMethodSignatureForSelector:selector]];
[invocation setSelector:selector];
[invocation setTarget:[UIDevice currentDevice]];
int val = UIInterfaceOrientationLandscapeRight;
[invocation setArgument:&val atIndex:2];
[invocation invoke];
}
對于IOS6及以后的版本. UIDevice.setOrientation從隱藏變為移除.只能通過設置UIView.transform 的方法來實現.
UIView.transform 最后一個方法是設置UIView 的transform屬性來強制旋轉.
見下代碼:
//設置statusBar
[[UIApplication sharedApplication] setStatusBarOrientation:orientation];
//計算旋轉角度
float arch;
if (orientation == UIInterfaceOrientationLandscapeLeft) {
rch = -M_PI_2;
} else if (orientation == UIInterfaceOrientationLandscapeRight) {
arch = M_PI_2;
} else {
arch = 0;
}
//對navigationController.view 進行強制旋轉
self.navigationController.view.transform = CGAffineTransformMakeRotation(arch);
self.navigationController.view.bounds = UIInterfaceOrientationIsLandscape(orientation) ? CGRectMake(0, 0, SCREEN_HEIGHT, SCREEN_WIDTH) : initialBounds;
需要注意的是:
1、當然我們可以對當前viewController進行旋轉, 對任何view旋轉都可以.但是, 你會發現navigationBar還橫在那里. 所以, 我們最好對一個占滿全屏的view進行旋轉. 在這里我們旋轉的對象是self.navigationController.view, 當然self.window也可以, help yourself~
2、我們需要顯式的設置bounds. UIKit并不知道你偷偷摸摸干了這些事情, 所以沒法幫你自動設置.
IOS6及以后
對于IOS6及以后的版本, 如果想方便的單獨控制每個viewController的方向. 則可以使用這樣:
對于非modal模式的viewController:如果不是rootViewController,則重寫supportedInterfaceOrientations,preferredInterfaceOrientationForPresentation以及shouldAutorotate方法, 按照當前viewController的需要返回響應的值.如果是rootViewController,則如下重寫方法:
-(NSUInteger)supportedInterfaceOrientations{
return self.topMostViewController.supportedInterfaceOrientations;
}
-(BOOL)shouldAutorotate{
return [self.topMostViewController shouldAutorotate];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
return [self.topMostViewController preferredInterfaceOrientationForPresentation];
}
-(UIViewController*)topMostViewController{
//找到當前正在顯示的viewController并返回.
}
顯而易見, 我們巧妙的繞開了UIKit只調用rootViewController的方法的規則. 把決定權交給了當前正在顯示的viewController.
對于modal
模式的viewController. 則按照需要重寫supportedInterfaceOrientations,
preferredInterfaceOrientationForPresentation
以及shouldAutorotate 方法即可.
四、強制屏幕旋轉
如果interface和device方向不一樣,想強制將interface旋轉成device的方向,可以通過attemptRotationToDeviceOrientation實現,但是如果想將interface強制旋轉成任一指定方向,該方式就無能為力了。
1、私有方法
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationPortrait];
2、旋轉view的transform
也可以通過旋轉view的transform屬性達到強制旋轉屏幕方向的目的,但個人感覺這不是靠譜的思路,可能會帶來某些詭異的問題。
3、主動觸發 orientation 機制
要是能主動觸發系統的 orientation 機制,調用 orientation 相關方法,使新設置的 orientation 值起作用就好了。這樣只要提前設置好想要支持的 orientation,然后主動觸發 orientation 機制,便能實現將 interface orientation旋轉至任意方向的目的。
關于手動旋轉的設置:
方式一、直接設置 UIDevice 的 orientation (可能被拒)
if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) {
[[UIDevice currentDevice] performSelector:@selector(setOrientation:) withObject:(id)UIInterfaceOrientationPortrait];
}
方式二、沒有改變 UIDevice 的 orientation,而是改變某個view的 transform,利用 CGAffineTransformMakeRotation 來達到目的,比如:
self.view.transform = CGAffineTransformMakeRotation(M_PI/2)
下面講解采用第二種方式的各版本手動旋轉:思想是首先設置 statusBarOrientation,然后再改變某個view的方向跟 statusBarOrientation 一致!
IOS6手動旋轉:
- 那既然是旋轉,最少也得有2個方向,那么還是少不了上面說的那個硬性條件,先在plist里面設置好所有可能需要旋轉的方向。既然是手動旋轉,那么就要關閉自動旋轉:
- (BOOL)shouldAutorotate{
return NO;
}
2.手動觸發某個按鈕,調用方法,這個方法的實現如下:
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight];
self.view.transform = CGAffineTransformMakeRotation(M_PI/2);
self.view.bounds = CGRectMake(0, 0, kScreenHeight, 320);
注意:
- 只需要改變self.view.transform,那么self.view的所有subview都會跟著自動變;其次因為方向變了,所以self.view的大小需要重新設置,不要使用self.view.frame,而是用bounds。
- 如果shouldAutorotate 返回YES的話,下面設置setStatusBarOrientation 是不管用的!setStatusBarOrientation只有在shouldAutorotate 返回NO的情況下才管用!
IOS5、IOS4手動旋轉:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
return (interfaceOrientation == [UIApplication sharedApplication].statusBarOrientation);
}
1.在需要手動旋轉的viewController里的 shouldAutorotateToInterfaceOrientation 方法設置 interfaceOrientation == [UIApplicationsharedApplication].statusBarOrientation
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
return (interfaceOrientation == [UIApplication sharedApplication].statusBarOrientation);
}
2.手動觸發某個按鈕,調用方法,這個方法的實現如下:
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight];
self.view.transform = CGAffineTransformMakeRotation(M_PI/2);
self.view.bounds = CGRectMake(0, 0, kScreenHeight, 320);
注意:只需要改變self.view.transform,那么self.view的所有subview都會跟著自動變;其次因為方向變了,所以self.view的大小需要重新設置,不要使用self.view.frame,而是用bounds。
經驗分享:
1.IOS6里面,如果一個項目里面需要各種旋轉支持,有自動,有手動,那么我們可以新建2個navController或者tabbarController的子類,一個是不旋轉,一個旋轉,那么所有需要旋轉的UINavigationController都可以用這個子類來代替!包括我們可以定制短信呀、郵件呀的旋轉!2.supportedInterfaceOrientations 方法一般是寫UIInterfaceOrientationMask方向,但是如果程序要兼容4.3以下的SDK(4.3以下的SDK必須是4.5以下的Xcode,不支持IOS6),那么在用4.5以下的Xcode編譯的時候通不過!所以可以用statusBarOrientation代替或者直接寫死數字!
-(NSUInteger)supportedInterfaceOrientations{
return [UIApplication sharedApplication].statusBarOrientation;
}
3.一般都不建議在程序里面直接調用 UIDeviceOrientation 的方向,而是用 UIInterfaceOrientation,他們之間是不同的!
UIInterfaceOrientationLandscapeLeft = UIDeviceOrientationLandscapeRight,
UIInterfaceOrientationLandscapeRight = UIDeviceOrientationLandscapeLeft
UIApplication.h
// Note that UIInterfaceOrientationLandscapeLeft is equal to UIDeviceOrientationLandscapeRight (and vice versa).
// This is because rotating the device to the left requires rotating the content to the right.
typedef NS_ENUM(NSInteger, UIInterfaceOrientation) {
UIInterfaceOrientationUnknown = UIDeviceOrientationUnknown,
UIInterfaceOrientationPortrait = UIDeviceOrientationPortrait,
UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown,
UIInterfaceOrientationLandscapeLeft = UIDeviceOrientationLandscapeRight,
UIInterfaceOrientationLandscapeRight = UIDeviceOrientationLandscapeLeft
} __TVOS_PROHIBITED;
/* This exception is raised if supportedInterfaceOrientations returns 0, or if preferredInterfaceOrientationForPresentation
returns an orientation that is not supported.
*/
UIKIT_EXTERN NSString *const UIApplicationInvalidInterfaceOrientationException NS_AVAILABLE_IOS(6_0) __TVOS_PROHIBITED;
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),
} __TVOS_PROHIBITED;
以組合的方式更加方便的使用這些枚舉值
萬能的stackoverflow上提供了一種主動觸發的方式:
UIViewController *vc = [[UIViewController alloc]init];
[self presentModalViewController:vc animated:NO];
[self dismissModalViewControllerAnimated:NO];
[vc release];