iOS 中的界面旋轉(zhuǎn)

級別: ★☆☆☆☆
標簽:「iOS」「界面旋轉(zhuǎn) 」「iOS 中的界面旋轉(zhuǎn)」
作者: dac_1033
審校: QiShare團隊


最近所接觸的項目中有幾處視頻播放的需求,在該項目中視頻播放器可以全屏/豎屏手動切換,也可以自動切換,但是其他界面都是豎屏狀態(tài)來展示。因此,總結(jié)了一下iOS中關(guān)于界面旋轉(zhuǎn),即橫屏/豎屏切換相關(guān)的一些知識點。

注意:在iOS中沒有顯式的設(shè)置界面方向的方法。

1. 視圖view的旋轉(zhuǎn)

如果需求是只對一個view進行旋轉(zhuǎn),我們可以直接調(diào)用以下方法,對視圖進行手動旋轉(zhuǎn)。

view.transform = CGAffineTransformMakeRotation(M_PI_2);

如果你想用此方式實現(xiàn)把app當前的整個界面都旋轉(zhuǎn)成橫屏,你可能還需要以下方法:

// 狀態(tài)欄也要旋轉(zhuǎn)
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeLeft animated:NO];

// 強制設(shè)置設(shè)備方向,以設(shè)置鍵盤彈出方向(注:但這是個私有方法)
[[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIDeviceOrientationLandscapeLeft] forKey:@"orientation"];

2. 用系統(tǒng)方法實現(xiàn)界面旋轉(zhuǎn)

用系統(tǒng)方法實現(xiàn)的是界面的自動旋轉(zhuǎn),首先,需要在工程中勾選一下選項:


image.png

其次,在AppDelegate中實現(xiàn)以下方法:

// 整個app允許的自動旋轉(zhuǎn)的方向
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
   
    return UIInterfaceOrientationMaskPortrait;
}

最后,在相應(yīng)的ViewController中實現(xiàn)一下系統(tǒng)方法:

// 是否能夠旋轉(zhuǎn)
- (BOOL)shouldAutorotate;

// 支持的旋轉(zhuǎn)方向
-(UIInterfaceOrientationMask)supportedInterfaceOrientations;

// 模態(tài)視圖初始化時的旋轉(zhuǎn)方向
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation;

屏幕旋轉(zhuǎn)是從全屏視圖的方法來判定的,即root視圖來判定的。也就是說每次判定頁面是否需要旋轉(zhuǎn)都是從圖中最左側(cè)的nav判定。我們要做到每個頁面自定義的話需要在UINavigationController和UITabbarController中分別實現(xiàn)如下方法:

//// 在NavgationController的基類中粘貼以下代碼
- (BOOL)shouldAutorotate {

    return self.topViewController.shouldAutorotate;
}
 
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {

    return self.topViewController.supportedInterfaceOrientations;
}
 
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {

    return [self.topViewController preferredInterfaceOrientationForPresentation];
}


////  在TabbarController的基類中粘貼以下代碼
- (BOOL)shouldAutorotate {

    return self.selectedViewController.shouldAutorotate;
}
 
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {

    return self.selectedViewController.supportedInterfaceOrientations;
}
 
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {

    return self.selectedViewController.preferredInterfaceOrientationForPresentation;
}

3. 獲取、監(jiān)聽設(shè)備的方向

  • 獲取設(shè)備方向
// 獲取設(shè)備方向
[[UIApplication sharedApplication] statusBarOrientation];
[[UIDevice currentDevice] orientation];
  • 添加監(jiān)聽設(shè)備旋轉(zhuǎn)的通知
// 添加監(jiān)聽設(shè)備旋轉(zhuǎn)的通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceOrientationChange:) name:UIDeviceOrientationDidChangeNotification object:nil];

- (void)deviceOrientationChange:(NSNotification *)notification {
    
    UIDeviceOrientation  orient = [UIDevice currentDevice].orientation;
    
    switch (orient) {
        case UIDeviceOrientationPortrait:
            
            break;
        case UIDeviceOrientationLandscapeLeft:
            
            break;
        case UIDeviceOrientationPortraitUpsideDown:
            
            break;
        case UIDeviceOrientationLandscapeRight:
            
            break;
            
        default:
            break;
    }
}


// 添加監(jiān)聽界面旋轉(zhuǎn)的通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(statusBarOrientationChange:) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];

- (void)statusBarOrientationChange:(NSNotification *)notification {
    
     UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
    
    if (orientation == UIInterfaceOrientationLandscapeRight) {
        
    }
    
    if (orientation ==UIInterfaceOrientationLandscapeLeft) {

    }
    
     if (orientation == UIInterfaceOrientationPortrait){
         
     }
    
    if (orientation == UIInterfaceOrientationPortraitUpsideDown){

    }
}

4. 界面旋轉(zhuǎn)的應(yīng)用實例

如開頭所說,如果app中有QiTabBarController、UINavigationController、UIViewController等多層次的界面情況下,我們只想讓某個界面自動旋轉(zhuǎn)功能,怎么實現(xiàn)呢?
(1)基類UITabBarController 、QiNavigationController中實現(xiàn)上面??的代碼;
(2)基類QiViewController中的shouldAutorotate方法返回NO;
(3)繼承于QiViewController的子controller中的shouldAutorotate方法返回YES,即可實現(xiàn)上述功能。

5. 強制某個界面旋轉(zhuǎn)

在iOS3以前可以通過UIDevice的setOrientation來實現(xiàn),但之后變成了私有方法,不能直接調(diào)用。我們利用 KVO機制去間接調(diào)用,是否能夠提交并成功發(fā)布至AppStore就靠運氣了!

//// 最直接的
[[UIDevice currentDevice] setValue:@(UIInterfaceOrientationPortrait) forKey:@"orientation"];


//// 含蓄的
- (void)forceOrientation {

    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;//橫屏
        [invocation setArgument:&val atIndex:2];
        [invocation invoke];
    }
}

工程源碼GitHub地址


推薦文章:
iOS 常用布局方式之Frame
iOS 常用布局方式之Autoresizing
iOS 常用布局方式之Constraint
iOS 常用布局方式之StackView
iOS 常用布局方式之Masonry
iOS UIButton根據(jù)內(nèi)容自動布局
iOS 指定初始化方法
UIView中的hitTest方法

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容