1、 iOS開發(fā)中一般情況只會用到豎屏甘凭,但有些app 的個別頁面卻要變成橫屏柬批,所以在很豎屏的切換就是一個經(jīng)常用到的問題。
- 一般情況下會用到一下幾個方法
// 是否支持屏幕旋轉(zhuǎn)
- (BOOL)shouldAutorotate {
return YES;
}
// 設(shè)置特殊的界面支持的方向
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
// 當(dāng)前設(shè)備支持的方向(橫屏方向)
return UIInterfaceOrientationMaskLandscape;
}
// 當(dāng)前設(shè)備的屏幕方向
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentatio {
// 當(dāng)前設(shè)備的屏幕方向(home 鍵在右邊)
return UIInterfaceOrientationLandscapeRight;
}
如果有
UINavigationController
或者是UITabBarController
等這些容器控制器的時候拐邪,上面方法就沒有了慰毅,底層控制器不是一般的UIViewController
- 所以需要在
UINavigationController
里面實現(xiàn)
// 是支持屏幕旋轉(zhuǎn)
- (BOOL)shouldAutorotate {
return [self.visibleViewController shouldAutorotate];
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return [self.visibleViewController supportedInterfaceOrientations];
}
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentatio {
return [self.visibleViewController preferredInterfaceOrientationForPresentation];
}
- 和在
UITabBarController
里面實現(xiàn)
// 是支持屏幕旋轉(zhuǎn)
- (BOOL)shouldAutorotate {
return [self.selectedViewController shouldAutorotate];
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return [self.selectedViewController supportedInterfaceOrientations];
}
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentatio {
return [self.selectedViewController preferredInterfaceOrientationForPresentation];
}
2、 但是這回出現(xiàn)的問題是庙睡,比如我直接跳轉(zhuǎn)倒膜個頁面事富,需要將當(dāng)前的豎屏變?yōu)闄M屏技俐,直接用上面的方法是行不通的。所以需要使用到 強(qiáng)制橫豎屏统台。在強(qiáng)制很豎屏前必須要明確當(dāng)前設(shè)備到底支持那些方向雕擂,然后才能讓你的設(shè)備支持具體的方向。這些方法寫在 viewDidLoad 里面沒有贱勃,一般寫在viewWillAppear:里面
// 強(qiáng)制旋轉(zhuǎn)屏幕到所需要的方向
- (void)resetInterfaceOrientation:(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;
// 從2開始是因為0 1 兩個參數(shù)已經(jīng)被selector和target占用
[invocation setArgument:&val atIndex:2];
[invocation invoke];
}
}
//強(qiáng)制旋轉(zhuǎn)屏幕方向
- (void)resetInterfaceOrientation:(UIInterfaceOrientation)Orientation {
//
NSNumber *orientationUnknown = [NSNumber numberWithInt:UIInterfaceOrientationUnknown];
[[UIDevice currentDevice] setValue:orientationUnknown forKey:@"orientation"];
//
NSNumber *orientationTarget = [NSNumber numberWithInt:Orientation];
[[UIDevice currentDevice] setValue:orientationTarget forKey:@"orientation"];
}
3井赌、 其他問題比如點(diǎn)擊某個按鈕,或者觸發(fā)某個事件后需要強(qiáng)制旋轉(zhuǎn)屏幕贵扰,同理也需要先去確定設(shè)備所支持的方向仇穗。這樣才可以相應(yīng)設(shè)備的當(dāng)前方向。
// (1)橫屏方法戚绕,先確定所需要支持的方向
self.supportLandscape = YES;
// 只支旋轉(zhuǎn)
- (BOOL)shouldAutorotate {
return YES;
}
// (2)然后在確定支持的方向
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
if (self.supportLandscape) {
return UIInterfaceOrientationMaskLandscape; //左右方向
} else {
return UIInterfaceOrientationMaskPortrait; //豎直方向
}
}
//(3)最后 強(qiáng)制旋轉(zhuǎn)屏幕到所需要的方向
- (void)resetInterfaceOrientation:(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];
}
}
4纹坐、還可以通過切換window的rootViewController 來實現(xiàn)橫豎屏,用此次方法來實現(xiàn)橫豎屏是不需要官切換前后的設(shè)備放下過是不是需要還原舞丛。這種方法需要在切換rootViewController之前講原來的rootViewController存儲起來耘子,以保證還原的時候可以還原原來的家控制器。
// 切換rootViewControler
ZHHorzonViewController *horVC = [[ZHHorzonViewController alloc] init];
horVC.rootVC = [UIApplication sharedApplication].keyWindow.rootViewController;
[UIApplication sharedApplication].keyWindow.rootViewController = horVC;
//還原rootVC
[UIApplication sharedApplication].keyWindow.rootViewController = self.rootVC;
5球切、 和全局控制谷誓,全局控制是通過 appdelegate 來實現(xiàn)的,向什么有 UINavigationController 和 UITabBarController 等的控制器一樣的處理
- 先為 appdelegate 注冊屬性用于確定方向
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
if (self.allowRotation == YES) {
//橫屏
return UIInterfaceOrientationMaskLandscape;
}else{
//豎屏
return UIInterfaceOrientationMaskPortrait;
}
}
- 然后在需要切換的地方先設(shè)置全局方向
// 全局控制
AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
delegate.allowRotation = YES;
- 最后在改變方向
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 = UIInterfaceOrientationLandscapeLeft;
// 從2開始是因為0 1 兩個參數(shù)已經(jīng)被selector和target占用
[invocation setArgument:&val atIndex:2];
[invocation invoke];
}
- 當(dāng)還原的時候吨凑,需要先控制支持的方向
// 全局控制
AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
delegate.allowRotation = NO;
// 還原為豎屏
NSNumber *orientationUnknown = [NSNumber numberWithInt:UIInterfaceOrientationUnknown];
[[UIDevice currentDevice] setValue:orientationUnknown forKey:@"orientation"];
NSNumber *orientationTarget = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
[[UIDevice currentDevice] setValue:orientationTarget forKey:@"orientation"];