本文只针对单个界面横竖屏界面
1.首先在TARGETS中将横竖屏勾选上(不用勾选貌似也可以,只不过需要在AppDelegate中,代码控制)
AppDelegate中控制横竖屏的代码如下
- (UIInterfaceOrientationMask )application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
//如果设置了allowRotation属性,支持全屏
if (self.allowRotation) {
return UIInterfaceOrientationMaskAllButUpsideDown;
}
return UIInterfaceOrientationMaskPortrait;//默认全局不支持横屏
}
2.主要利用通知来实现,AppDelegate中创建BOOL值allowRotation
- (void)addNotificationCenter
{
//在进入需要全屏的界面里面发送需要全屏的通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(startFullScreen) name:@"startFullScreen" object:nil];//进入全屏
//在退出需要全屏的界面里面发送退出全屏的通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(endFullScreen) name:@"endFullScreen" object:nil];//退出全屏
}
#pragma mark 进入全屏
-(void)startFullScreen
{
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
appDelegate.allowRotation = YES;
}
#pragma mark 退出横屏
-(void)endFullScreen
{
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
appDelegate.allowRotation = NO;
//强制归正:
[[AnyeToolManager shareManager] setOrientationInterfaceOrientationPortrait];
}
#pragma mark 禁止横屏
- (UIInterfaceOrientationMask )application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
//如果设置了allowRotation属性,支持全屏
if (self.allowRotation) {
return UIInterfaceOrientationMaskAllButUpsideDown;
}
return UIInterfaceOrientationMaskPortrait;//默认全局不支持横屏
}
强制归正的代码:
1.第一种,据说调用私有变量,可能被拒
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 =UIInterfaceOrientationPortrait;
[invocation setArgument:&val atIndex:2];
[invocation invoke];
}
2.第二种,利用KVO,目前采用此方法,会不会被拒尚未知,等项目上线后回来更新(项目已上线,用此种方法可以通过审核)
NSNumber *orientationUnknown = [NSNumber numberWithInt:UIInterfaceOrientationUnknown];
[[UIDevice currentDevice] setValue:orientationUnknown forKey:@"orientation"];
NSNumber *orientationTarget = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
[[UIDevice currentDevice] setValue:orientationTarget forKey:@"orientation"];
其实后两行代码就可以满足需求,至于前两行代码的原因,这里有答案http://www.jianshu.com/p/6c45fa2bb970
3.在需要横屏的控制器的viewWillAppear和viewWillDisappear中分别发送可以横屏和取消横屏的通知
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
//发送全屏通知
[[NSNotificationCenter defaultCenter] postNotificationName:@"startFullScreen" object:nil];
//强制归正
[[AnyeToolManager shareManager] setOrientationInterfaceOrientationPortrait];
}
-(void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
//发送非全屏通知
[[NSNotificationCenter defaultCenter] postNotificationName:@"endFullScreen" object:nil];
}
4.搞定,不过有BUG,在横屏模式下,退出到不可以横屏的控制器,会默认先回正,再pop,视觉上不是很好,这个问题正在研究...
5.另外,在我处理横竖屏切换的过程中,遇到一个问题,切换动画消失,也就是,竖屏到横屏的过程很突然,没有旋转的过程,也算是一个奇葩.经过大量的谷歌百度,竟然搜不到任何相关,好在最后意外解决,也算是惊喜,方法如下
-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
[UIView beginAnimations:@"rotate" context:nil];
[UIView setAnimationDuration:ReadAnimationLeftRightTimeInterval];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.05 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[UIView commitAnimations];//一定要停止,不停止的话,整个APP的所有的动画都会出异常
});
}
viewWillTransitionToSize:(CGSize)size withTransitionCoordinator方法会在横竖屏切换的时候调用,在这个方法中让UIView的rotate动画beginAnimation,并且切记要执行 [UIView commitAnimations],而且此方法千万不要立即执行,延迟一点时间,不然还是没动画,但如果不执行的话,整个APP的所有的动画都会出异常
其实这种方法也有好处,就是可以调整横竖屏切换的时间
[UIView setAnimationDuration:ReadAnimationLeftRightTimeInterval];
我这里的ReadAnimationLeftRightTimeInterval只是个宏,可以根据所需调整