一、屏幕旋轉(zhuǎn)優(yōu)先級(jí)
Target屬性配置或者Info.plist設(shè)置 = AppDelegate中設(shè)置 > 根視圖控制器 > 普通視圖控制器创坞。
如果高優(yōu)先級(jí)的已經(jīng)關(guān)閉了导犹,低優(yōu)先級(jí)就不會(huì)生效裹赴,如:AppDelegate中關(guān)閉了屏幕旋轉(zhuǎn),即使在根視圖控制器中開(kāi)啟了屏幕旋轉(zhuǎn)么鹤,也不會(huì)生效终娃。
一、全局權(quán)限
1.TARGETS->Device Orientation中設(shè)置
iPhone沒(méi)有UpSide Down的旋轉(zhuǎn)效果蒸甜,勾選也不生效棠耕。但iPad支持余佛。
對(duì)于iPhone,如果四個(gè)屬性都選或者都不選窍荧,效果和默認(rèn)的情況一樣辉巡。
2.Info.plist中設(shè)置
Info.plist里的設(shè)置與TARGETS->Device Orientation是一致的,修改一方蕊退,另一方會(huì)同步修改郊楣。
3.AppDelegate中設(shè)置
- (UIInterfaceOrientationMask)application:(UIApplication *)application
supportedInterfaceOrientationsForWindow:(UIWindow *)window {
return UIInterfaceOrientationMaskAll;
}
如果在AppDelegate中進(jìn)行了設(shè)置,那么App的全局旋轉(zhuǎn)將以AppDelegate中設(shè)置為準(zhǔn)瓤荔,即使前兩種方法的設(shè)置與這里的不同净蚤。
二、局部權(quán)限
主要涉及三種視圖控制器:UITabbarViewController输硝、UINavigationBarController今瀑、UIViewController。
全局權(quán)限之后腔丧,接下來(lái)具有最高權(quán)限的就是window的根視圖控制器rootViewController了放椰。如果要具體控制單個(gè)界面UIViewController的旋轉(zhuǎn)就必須先看一下根視圖控制器的配置情況。
如果項(xiàng)目結(jié)構(gòu)為:window的rootViewController為UITabbarViewController愉粤,UITabbarViewController管理著若干UINavigationBarController砾医,UINavigationBarController管理著若干UIViewController。
此時(shí)的旋轉(zhuǎn)優(yōu)先級(jí)為:UITabbarViewController > UINavigationBarController > UIViewController衣厘。
二如蚜、屏幕旋轉(zhuǎn)涉及的三種枚舉
一、設(shè)備方向:UIDeviceOrientation
UIDeviceOrientation是硬件設(shè)備(iPhone影暴、iPad等)本身的當(dāng)前旋轉(zhuǎn)方向错邦,設(shè)備方向有7種(包括一種未知的情況),判斷設(shè)備的方向是以home鍵的位置作為參照的:
typedef NS_ENUM(NSInteger, UIDeviceOrientation) {
UIDeviceOrientationUnknown,
UIDeviceOrientationPortrait, // Device oriented vertically, home button on the bottom
UIDeviceOrientationPortraitUpsideDown, // Device oriented vertically, home button on the top
UIDeviceOrientationLandscapeLeft, // Device oriented horizontally, home button on the right
UIDeviceOrientationLandscapeRight, // Device oriented horizontally, home button on the left
UIDeviceOrientationFaceUp, // Device oriented flat, face up
UIDeviceOrientationFaceDown // Device oriented flat, face down
}
設(shè)備方向只能取值型宙,不能設(shè)置撬呢。
獲取設(shè)備當(dāng)前旋轉(zhuǎn)方向使用方法:[UIDevice currentDevice].orientation
通過(guò)監(jiān)聽(tīng):UIDeviceOrientationDidChangeNotification
可以檢測(cè)設(shè)備方向變化。
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onDeviceOrientationDidChange)
name:UIDeviceOrientationDidChangeNotification
object:nil];
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
如果在iPhone的控制臺(tái)上關(guān)閉了屏幕自動(dòng)旋轉(zhuǎn)妆兑,則當(dāng)手機(jī)方向改變時(shí)魂拦,該通知無(wú)法監(jiān)聽(tīng)到。但可以監(jiān)聽(tīng)到代碼層面主動(dòng)發(fā)起的屏幕旋轉(zhuǎn)搁嗓。
- (void)deviceOrientationDidChange {
UIDevice *device = [UIDevice currentDevice];
switch (device.orientation) {
case UIDeviceOrientationFaceUp:
NSLog(@"屏幕幕朝上平躺");
break;
case UIDeviceOrientationFaceDown:
NSLog(@"屏幕朝下平躺");
break;
case UIDeviceOrientationUnknown:
//系統(tǒng)當(dāng)前無(wú)法識(shí)別設(shè)備朝向芯勘,可能是傾斜
NSLog(@"未知方向");
break;
case UIDeviceOrientationLandscapeLeft:
NSLog(@"屏幕向左橫置");
break;
case UIDeviceOrientationLandscapeRight:
NSLog(@"屏幕向右橫置");
break;
case UIDeviceOrientationPortrait:
NSLog(@"屏幕直立");
break;
case UIDeviceOrientationPortraitUpsideDown:
NSLog(@"屏幕直立,上下顛倒");
break;
default:
NSLog(@"無(wú)法識(shí)別");
break;
}
}
二腺逛、頁(yè)面方向:UIInterfaceOrientation
注意:頁(yè)面方向與設(shè)備方向大部分是可以對(duì)應(yīng)的色建,但左右旋轉(zhuǎn)是反著的网沾。這是因?yàn)轫?yè)面方向如果向左难礼,也就意味著設(shè)置需要向右旋轉(zhuǎn)富雅。
typedef NS_ENUM(NSInteger, UIInterfaceOrientation) {
UIInterfaceOrientationUnknown = UIDeviceOrientationUnknown,
UIInterfaceOrientationPortrait = UIDeviceOrientationPortrait,
UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown,
UIInterfaceOrientationLandscapeLeft = UIDeviceOrientationLandscapeRight,
UIInterfaceOrientationLandscapeRight = UIDeviceOrientationLandscapeLeft
}
三、頁(yè)面方向:UIInterfaceOrientationMask
這是為了支持多種UIInterfaceOrientation而定義的類型。
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),
}
三、控制屏幕旋轉(zhuǎn)
以下是控制屏幕旋轉(zhuǎn)的函數(shù)。不管是自動(dòng)旋轉(zhuǎn)還是強(qiáng)制旋轉(zhuǎn)蝶桶,都需要設(shè)置shouldAutorotate
為YES
,supportedInterfaceOrientations
里對(duì)應(yīng)的為當(dāng)前界面支持的旋轉(zhuǎn)方向掉冶,preferredInterfaceOrientationForPresentation
這個(gè)函數(shù)經(jīng)測(cè)試沒(méi)有被調(diào)用真竖,且不起作用,暫不做討論厌小。
///開(kāi)啟支持設(shè)備自動(dòng)旋轉(zhuǎn)
- (BOOL)shouldAutorotate {
return YES;
}
///支持屏幕旋轉(zhuǎn)的方向
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskAll;
}
/// 默認(rèn)進(jìn)入界面顯示方向
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationLandscapeRight;
}
一恢共、自動(dòng)旋轉(zhuǎn)
如果配置了上面的旋轉(zhuǎn)函數(shù)且沒(méi)有在iPhone的控制臺(tái)上關(guān)閉屏幕自動(dòng)旋轉(zhuǎn),則支持旋轉(zhuǎn)的界面在設(shè)備旋轉(zhuǎn)后璧亚,會(huì)自動(dòng)進(jìn)行旋轉(zhuǎn)讨韭。如果在控制臺(tái)關(guān)閉了,則自動(dòng)旋轉(zhuǎn)會(huì)失效癣蟋。
二透硝、強(qiáng)制旋轉(zhuǎn)
如果配置了上面的旋轉(zhuǎn)函數(shù),則可以通過(guò)下面兩個(gè)方法來(lái)強(qiáng)制使界面旋轉(zhuǎn)疯搅,這兩個(gè)方法任選其一即可濒生。
//方法1和方法2只有在shouldAutorotate返回YES的時(shí)候生效
//方法1:強(qiáng)制屏幕旋轉(zhuǎn)
- (void)setInterfaceOrientation:(UIInterfaceOrientation)orientation {
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 = orientation;
[invocation setArgument:&val atIndex:2];
[invocation invoke];
}
}
//方法2:強(qiáng)制屏幕旋轉(zhuǎn)
- (void)setDeviceInterfaceOrientation:(UIDeviceOrientation)orientation {
if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) {
[[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:orientation] forKey:@"orientation"];
}
}
四、屏幕旋轉(zhuǎn)場(chǎng)景
假設(shè)項(xiàng)目結(jié)構(gòu)為:window的rootViewController為UITabbarViewController幔欧,UITabbarViewController管理著若干UINavigationBarController罪治,UINavigationBarController管理著若干UIViewController。
一礁蔗、全部界面支持旋轉(zhuǎn)
只需設(shè)置全局權(quán)限觉义。
二、大部分界面豎屏浴井,個(gè)別界面旋轉(zhuǎn)
一晒骇、通用設(shè)置
1.在AppDelegate中設(shè)置全局旋轉(zhuǎn)模式為支持旋轉(zhuǎn)
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
return UIInterfaceOrientationMaskAll;
}
2.在UITabbarViewController中設(shè)置局部權(quán)限為跟隨當(dāng)前的子控制器(被選中的tabbar對(duì)應(yīng)的控制器)
//是否自動(dòng)旋轉(zhuǎn)
-(BOOL)shouldAutorotate {
return self.selectedViewController.shouldAutorotate;
}
//支持哪些屏幕方向
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return [self.selectedViewController supportedInterfaceOrientations];
}
//默認(rèn)方向
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return [self.selectedViewController preferredInterfaceOrientationForPresentation];
}
3.在UINavigationBarController中設(shè)置局部權(quán)限為跟隨當(dāng)前的子控制器(因?yàn)閷?dǎo)航控制器是以入棧的形式,故topViewController對(duì)應(yīng)的就是當(dāng)前顯示的UIViewController)
//是否自動(dòng)旋轉(zhuǎn)
//返回導(dǎo)航控制器的頂層視圖控制器的自動(dòng)旋轉(zhuǎn)屬性磺浙,
//topViewController是其最頂層的視圖控制器洪囤,
-(BOOL)shouldAutorotate {
return self.topViewController.shouldAutorotate;
}
//支持哪些屏幕方向
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return [self.topViewController supportedInterfaceOrientations];
}
//默認(rèn)方向
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return [self.topViewController preferredInterfaceOrientationForPresentation];
}
4.在UIViewController中設(shè)置當(dāng)前控制器需要旋轉(zhuǎn)的方向
///開(kāi)啟支持設(shè)備自動(dòng)旋轉(zhuǎn)
- (BOOL)shouldAutorotate {
return YES;
}
///支持屏幕旋轉(zhuǎn)的方向
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskAll;
}
/// 默認(rèn)進(jìn)入界面顯示方向
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationLandscapeRight;
}
5.經(jīng)過(guò)上面的設(shè)置后,UIViewController就可以支持界面旋轉(zhuǎn)了屠缭。如果設(shè)置supportedInterfaceOrientations
為UIInterfaceOrientationMaskLandscapeRight
箍鼓,則當(dāng)前界面進(jìn)入后會(huì)不會(huì)自動(dòng)橫屏顯示崭参,需要設(shè)備旋轉(zhuǎn)后才會(huì)橫屏呵曹,如想進(jìn)入后自動(dòng)橫屏,參考特殊設(shè)置2.
如果設(shè)置為UIInterfaceOrientationMaskAll
,當(dāng)前界面默認(rèn)豎屏奄喂。
6.但是上面的設(shè)置有瑕疵铐殃,會(huì)出現(xiàn)不想旋轉(zhuǎn)的UIViewController也能旋轉(zhuǎn),如果想關(guān)閉某些UIViewController的旋轉(zhuǎn)跨新,需要在他們里面重寫(xiě)上面的方法富腊。為了避免這個(gè)問(wèn)題,可以創(chuàng)建個(gè)父類:BaseViewController域帐,讓所有的UIViewController繼承自BaseViewController赘被。在BaseViewController中關(guān)閉自動(dòng)旋轉(zhuǎn),在需要旋轉(zhuǎn)的UIViewController中重寫(xiě)上面的方法肖揣。這樣代碼比較健全民假,且避免其他問(wèn)題出現(xiàn)。
二龙优、特殊設(shè)置
1.如果想讓界面push時(shí)默認(rèn)豎屏羊异,點(diǎn)擊按鈕后橫屏,同時(shí)不受設(shè)備旋轉(zhuǎn)的影響(即無(wú)論設(shè)備怎么旋轉(zhuǎn)彤断,界面方向都保持我們?cè)O(shè)置的方向)野舶,則需要做特殊設(shè)置:把supportedInterfaceOrientations
的返回值設(shè)置為動(dòng)態(tài)可調(diào)整的。
/// 聲明一個(gè)靜態(tài)變量標(biāo)識(shí)當(dāng)前界面支持的旋轉(zhuǎn)方向
static UIInterfaceOrientationMask interfaceOrientations;
/// 默認(rèn)當(dāng)前界面只支持豎屏
+ (void)initialize {
interfaceOrientations = UIInterfaceOrientationMaskPortrait;
}
- (IBAction)handleBtnAction:(id)sender {
///在需要橫屏?xí)r宰衙,調(diào)整當(dāng)面界面支持的旋轉(zhuǎn)方向?yàn)闄M屏
interfaceOrientations = UIInterfaceOrientationMaskLandscapeRight;
[self setInterfaceOrientation:UIInterfaceOrientationLandscapeRight];
}
///支持屏幕旋轉(zhuǎn)的方向
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
///返回設(shè)置的當(dāng)前界面支持的旋轉(zhuǎn)方向
return interfaceOrientations;
}
2.如果想讓界面進(jìn)入后就橫屏平道,則需要在viewWillAppear
時(shí)主動(dòng)調(diào)用強(qiáng)制旋轉(zhuǎn)接口:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self setInterfaceOrientation:UIInterfaceOrientationLandscapeRight];
}
- (void)setInterfaceOrientation:(UIInterfaceOrientation)orientation {
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 = orientation;
[invocation setArgument:&val atIndex:2];
[invocation invoke];
}
}
///開(kāi)啟支持設(shè)備自動(dòng)旋轉(zhuǎn)
- (BOOL)shouldAutorotate {
return YES;
}
///支持屏幕旋轉(zhuǎn)的方向
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
///返回設(shè)置的當(dāng)前界面支持的旋轉(zhuǎn)方向
return UIInterfaceOrientationMaskLandscapeRight;
}
/// 默認(rèn)進(jìn)入界面顯示方向
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationLandscapeRight;
}
三、模態(tài)視圖
模態(tài)視圖不受上述所有的限制供炼,這是因?yàn)槟B(tài)彈出的視圖控制器是隔離出來(lái)的巢掺,不受根視圖控制的影響。
1.在AppDelegate中設(shè)置全局旋轉(zhuǎn)模式為支持旋轉(zhuǎn)
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
return UIInterfaceOrientationMaskAll;
}
2.設(shè)置模態(tài)視圖的局部權(quán)限
///開(kāi)啟支持設(shè)備自動(dòng)旋轉(zhuǎn)
- (BOOL)shouldAutorotate {
return YES;
}
///支持屏幕旋轉(zhuǎn)的方向
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscapeRight;
}
/// 默認(rèn)進(jìn)入界面顯示方向
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationLandscapeRight;
}
3.模態(tài)出該視圖
FHSecondVC *vc = [[FHSecondVC alloc] init];
vc.modalPresentationStyle = UIModalPresentationFullScreen;
[self presentViewController:vc animated:YES completion:^{
}];
注意:模態(tài)時(shí)一定要設(shè)置模式為:UIModalPresentationFullScreen
劲蜻,旋轉(zhuǎn)才能生效陆淀。
其他屏幕旋轉(zhuǎn)文章:
http://www.reibang.com/p/a354ca1890de