iOS 橫豎屏切換

本文只針對(duì)單個(gè)界面橫豎屏界面

1.首先在TARGETS中將橫豎屏勾選上(不用勾選貌似也可以,只不過需要在AppDelegate中,代碼控制)

image.png

AppDelegate中控制橫豎屏的代碼如下

- (UIInterfaceOrientationMask )application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
    //如果設(shè)置了allowRotation屬性,支持全屏
    if (self.allowRotation) {
        return UIInterfaceOrientationMaskAllButUpsideDown;
    }
    return UIInterfaceOrientationMaskPortrait;//默認(rèn)全局不支持橫屏
}

2.主要利用通知來實(shí)現(xiàn),AppDelegate中創(chuàng)建BOOL值allowRotation

- (void)addNotificationCenter
{
    //在進(jìn)入需要全屏的界面里面發(fā)送需要全屏的通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(startFullScreen) name:@"startFullScreen" object:nil];//進(jìn)入全屏
    //在退出需要全屏的界面里面發(fā)送退出全屏的通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(endFullScreen) name:@"endFullScreen" object:nil];//退出全屏
}
#pragma mark 進(jìn)入全屏
-(void)startFullScreen
{
    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    appDelegate.allowRotation = YES;
}
#pragma mark    退出橫屏
-(void)endFullScreen
{
    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    appDelegate.allowRotation = NO;
    //強(qiáng)制歸正:
    [[AnyeToolManager shareManager] setOrientationInterfaceOrientationPortrait];
}
#pragma mark    禁止橫屏
- (UIInterfaceOrientationMask )application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
    //如果設(shè)置了allowRotation屬性,支持全屏
    if (self.allowRotation) {
        return UIInterfaceOrientationMaskAllButUpsideDown;
    }
    return UIInterfaceOrientationMaskPortrait;//默認(rèn)全局不支持橫屏
}

強(qiáng)制歸正的代碼:
1.第一種,據(jù)說調(diào)用私有變量,可能被拒

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,目前采用此方法,會(huì)不會(huì)被拒尚未知,等項(xiàng)目上線后回來更新(項(xiàng)目已上線,用此種方法可以通過審核)

    NSNumber *orientationUnknown = [NSNumber numberWithInt:UIInterfaceOrientationUnknown];
    [[UIDevice currentDevice] setValue:orientationUnknown forKey:@"orientation"];
    
    NSNumber *orientationTarget = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
    [[UIDevice currentDevice] setValue:orientationTarget forKey:@"orientation"];

其實(shí)后兩行代碼就可以滿足需求,至于前兩行代碼的原因,這里有答案http://www.lxweimin.com/p/6c45fa2bb970

3.在需要橫屏的控制器的viewWillAppear和viewWillDisappear中分別發(fā)送可以橫屏和取消橫屏的通知

-(void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];    
    //發(fā)送全屏通知
    [[NSNotificationCenter defaultCenter] postNotificationName:@"startFullScreen" object:nil];
    //強(qiáng)制歸正
    [[AnyeToolManager shareManager] setOrientationInterfaceOrientationPortrait];
}
-(void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    //發(fā)送非全屏通知
    [[NSNotificationCenter defaultCenter] postNotificationName:@"endFullScreen" object:nil];
}

4.搞定,不過有BUG,在橫屏模式下,退出到不可以橫屏的控制器,會(huì)默認(rèn)先回正,再pop,視覺上不是很好,這個(gè)問題正在研究...

5.另外,在我處理橫豎屏切換的過程中,遇到一個(gè)問題,切換動(dòng)畫消失,也就是,豎屏到橫屏的過程很突然,沒有旋轉(zhuǎn)的過程,也算是一個(gè)奇葩.經(jīng)過大量的谷歌百度,竟然搜不到任何相關(guān),好在最后意外解決,也算是驚喜,方法如下

-(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];//一定要停止,不停止的話,整個(gè)APP的所有的動(dòng)畫都會(huì)出異常
    });
    
}

viewWillTransitionToSize:(CGSize)size withTransitionCoordinator方法會(huì)在橫豎屏切換的時(shí)候調(diào)用,在這個(gè)方法中讓UIView的rotate動(dòng)畫beginAnimation,并且切記要執(zhí)行 [UIView commitAnimations],而且此方法千萬不要立即執(zhí)行,延遲一點(diǎn)時(shí)間,不然還是沒動(dòng)畫,但如果不執(zhí)行的話,整個(gè)APP的所有的動(dòng)畫都會(huì)出異常
其實(shí)這種方法也有好處,就是可以調(diào)整橫豎屏切換的時(shí)間

[UIView setAnimationDuration:ReadAnimationLeftRightTimeInterval];

我這里的ReadAnimationLeftRightTimeInterval只是個(gè)宏,可以根據(jù)所需調(diào)整

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • iOS 中橫豎屏切換的功能,在開發(fā)iOS app中總能遇到。以前看過幾次,感覺簡(jiǎn)單,但是沒有敲過代碼實(shí)現(xiàn),最近又碰...
    零度_不結(jié)冰閱讀 2,238評(píng)論 0 0
  • 網(wǎng)上關(guān)于橫豎屏切換的資料很多,但是很容易踩到坑,不是屏幕不旋轉(zhuǎn),就是屏幕旋轉(zhuǎn)后沒有狀態(tài)欄等,在寫的小demo里屏幕...
    凌云01閱讀 561評(píng)論 0 0
  • 進(jìn)入正文前先認(rèn)識(shí)幾個(gè)概念 portrait 豎屏(Home鍵在下邊) upside down 豎屏(Home鍵在上...
    hallfrita閱讀 1,490評(píng)論 0 2
  • 導(dǎo)航控制器PUSH 需求:當(dāng)前豎屏下情況下,導(dǎo)航欄直接PUSH出一個(gè)橫屏的控制器,并在POP后返回豎屏狀態(tài)。效果圖...
    毅個(gè)天亮閱讀 994評(píng)論 0 1
  • 在網(wǎng)上找iOS橫屏相關(guān)的信息時(shí)發(fā)現(xiàn)只有進(jìn)入頁面強(qiáng)制橫屏的代碼,并沒有在一個(gè)頁面通過點(diǎn)擊按鈕的方式實(shí)現(xiàn)當(dāng)前屏幕的橫豎...
    iOS_Edward閱讀 1,761評(píng)論 4 1