在项目中遇到了一个问题,app中有两个控制器要求可以切换横屏,研究了半天,终于找到了解决办法.
在AppDelegate中写
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
- (
UIInterfaceOrientationMask
)application:(
UIApplication
*)application supportedInterfaceOrientationsForWindow:(
UIWindow
*)window{
NSUInteger
orientations =
UIInterfaceOrientationMaskAllButUpsideDown
;
if
(
self
.window.rootViewController){
UIViewController
*presentedViewController = [
self
topViewControllerWithRootViewController:
self
.window.rootViewController];
orientations = [presentedViewController supportedInterfaceOrientations];
}
return
orientations;
}
- (
UIViewController
*)topViewControllerWithRootViewController:(
UIViewController
*)rootViewController {
if
([rootViewController isKindOfClass:[
UITabBarController
class
]]) {
UITabBarController
* tabBarController = (
UITabBarController
*)rootViewController;
return
[
self
topViewControllerWithRootViewController:tabBarController.selectedViewController];
}
else
if
([rootViewController isKindOfClass:[
UINavigationController
class
]]) {
UINavigationController
* navigationController = (
UINavigationController
*)rootViewController;
return
[
self
topViewControllerWithRootViewController:navigationController.visibleViewController];
}
else
if
(rootViewController.presentedViewController) {
UIViewController
* presentedViewController = rootViewController.presentedViewController;
return
[
self
topViewControllerWithRootViewController:presentedViewController];
}
else
{
return
rootViewController;
}
}
|
再到各个控制器中写上要旋转的方向
1
2
3
|
- (
UIInterfaceOrientationMask
)supportedInterfaceOrientations{
return
UIInterfaceOrientationMaskPortrait
;
}
|
但目前看来还是不够完美,还有两个问题:
-
在一个界面切换横屏后再pop回来,发现前一个界面也变成横屏了,必须再转动手机才能正常;
-
如果手动点击按钮切换横屏竖屏的话,暂时无法屏蔽自动横屏(重力感应);
代码在这里:https://github.com/XanderXu/RotateOneVC
正常竖屏:
转动手机,界面不变
哈哈,经过研究,手动切换横屏界面的bug已经消除了.(setOrientation是私有方法,上架可能会被拒,也可能没问题)
看代码
```objc
-(void)viewWillDisappear:(BOOL)animated {
//界面消失时,切换回竖屏,不影响前一个/后一个控制器的界面,也不影响输入法....
self.portrait = YES;
SEL selector = NSSelectorFromString(@"setOrientation:");
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDeviceinstanceMethodSignatureForSelector:selector]];
[invocation setSelector:selector];
[invocation setTarget:[UIDevice currentDevice]];
int val = UIDeviceOrientationPortrait;
//从2开始是因为0 1 两个参数已经被selector和target占用
[invocation setArgument:&val atIndex:2];
[invocation invoke];
}
- (IBAction)rotate:(id)sender {
if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) {
if (self.isPortrait) {//当前是竖屏,则切换为横屏
self.portrait = false;
[[UIDevice currentDevice] performSelector:@selector(setOrientation:) withObject:[NSNumber numberWithInteger:UIInterfaceOrientationMaskLandscapeLeft]];
}else {//当前是横屏,则切换为竖屏
self.portrait = YES;
SEL selector = NSSelectorFromString(@"setOrientation:");
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDevice instanceMethodSignatureForSelector:selector]];
[invocation setSelector:selector];
[invocation setTarget:[UIDevice currentDevice]];
int val = UIDeviceOrientationPortrait;
//从2开始是因为0 1 两个参数已经被selector和target占用
[invocation setArgument:&val atIndex:2];
[invocation invoke];
}
}
}
-(UIInterfaceOrientationMask)supportedInterfaceOrientations {
if (self.isPortrait) {//当前竖屏不让自动切换,只能保持竖屏
return UIInterfaceOrientationMaskPortrait;
}else {//当前横屏不让自动切换,只能保持横屏
return UIInterfaceOrientationMaskLandscape;
}
}
```
关于屏幕旋转的一些问题,可以看这里的讲解: