本文只針對單個界面橫豎屏界面
1.首先在TARGETS中將橫豎屏勾選上(不用勾選貌似也可以,只不過需要在AppDelegate中,代碼控制)
image.png
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.lxweimin.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只是個宏,可以根據所需調整