iOS監(jiān)聽屏幕旋轉(zhuǎn)的幾種方式

1. 使用viewWillTransitionToSize:withTransitionCoordinator: 監(jiān)聽屏幕旋轉(zhuǎn):

iOS9之前,最常用的監(jiān)聽函數(shù)是如下兩個:

//轉(zhuǎn)屏前回調(diào)函數(shù)
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)durationNS_DEPRECATED_IOS(3_0,8_0,"Implement viewWillTransitionToSize:withTransitionCoordinator: instead")__TVOS_PROHIBITED;
 
//轉(zhuǎn)屏后回調(diào)函數(shù)
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientationNS_DEPRECATED_IOS(2_0,8_0)__TVOS_PROHIBITED;

但這兩個協(xié)議方法已經(jīng)在iOS9之后廢棄了(雖然也可以繼續(xù)調(diào)用,但官方不建議使用了)
文檔提示,改用如下函數(shù):

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator;

轉(zhuǎn)屏前后的監(jiān)聽如下:

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id <UIViewControllerTransitionCoordinator>)coordinator
{
    [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context){
        NSLog(@"轉(zhuǎn)屏前調(diào)入");
    } completion:^(id<UIViewControllerTransitionCoordinatorContext> context){
        NSLog(@"轉(zhuǎn)屏后調(diào)入");
    }];
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
}

但這個監(jiān)聽方法有個局限性,這個協(xié)議方法來自于<UIContentContainer>,而查看官方代碼可知,只有UIViewController及其子類,才能遵循并實現(xiàn)這個協(xié)議方法。即只有UIViewController才能夠使用這個方法監(jiān)聽到 (且UIViewController是以一個類實例存在的)。

2. 通過 UIDeviceOrientationDidChangeNotification 通知監(jiān)聽:
-(void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];
    //開始生成 設(shè)備旋轉(zhuǎn) 通知
    [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
 
    //添加 設(shè)備旋轉(zhuǎn) 通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientChange:)  name:UIDeviceOrientationDidChangeNotification object:nil];
}
 
-(void)viewDidDisappear:(BOOL)animated{
    [super viewDidDisappear:animated];
    //銷毀 設(shè)備旋轉(zhuǎn) 通知
    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:UIDeviceOrientationDidChangeNotification
                                                  object:nil
     ];
 
    //結(jié)束 設(shè)備旋轉(zhuǎn)通知
    [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
}
 
/**屏幕旋轉(zhuǎn)的通知回調(diào)*/
- (void)orientChange:(NSNotification *)noti {
    UIDeviceOrientation  orient = [UIDevice currentDevice].orientation;
    switch (orient) {
        case UIDeviceOrientationPortrait:
            NSLog(@"豎直屏幕");
            break;
        case UIDeviceOrientationLandscapeLeft:
            NSLog(@"手機左轉(zhuǎn)");
            break;
        case UIDeviceOrientationPortraitUpsideDown:
            NSLog(@"手機豎直");
            break;
        case UIDeviceOrientationLandscapeRight:
            NSLog(@"手機右轉(zhuǎn)");
            break;
        case UIDeviceOrientationUnknown:
            NSLog(@"未知");
            break;
        case UIDeviceOrientationFaceUp:
            NSLog(@"手機屏幕朝上");
            break;
        case UIDeviceOrientationFaceDown:
            NSLog(@"手機屏幕朝下");
            break;
        default:
            break;
    }
}

這里監(jiān)聽的是屏幕方向。UIDeviceOrientation除了橫豎屏4個方向以外,還包括“屏幕朝上”、“屏幕朝下”這兩個方向,處理業(yè)務(wù)邏輯時需要注意著兩個方向的特殊性。
因為通知的便利性,所以監(jiān)聽不需要局限于UIViewController里,而是任意位置。但注意要及時移除掉通知。

3. 通過 UIApplicationDidChangeStatusBarOrientationNotification 通知監(jiān)聽:
- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    //添加 設(shè)備旋轉(zhuǎn) 通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientChange:) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];
}
 
-(void)viewDidDisappear:(BOOL)animated{
    [super viewDidDisappear:animated];
    //銷毀 設(shè)備旋轉(zhuǎn) 通知
    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:UIApplicationDidChangeStatusBarOrientationNotification
                                                  object:nil];
}
 
/**屏幕旋轉(zhuǎn)的通知回調(diào)*/
- (void)orientChange:(NSNotification *)noti {
    UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
    switch (orientation) {
        case UIInterfaceOrientationUnknown:
            NSLog(@"未知");
            break;
        case UIInterfaceOrientationPortrait:
            NSLog(@"豎直");
            break;
        case UIInterfaceOrientationPortraitUpsideDown:
            NSLog(@"屏幕倒立");
            break;
        case UIInterfaceOrientationLandscapeLeft:
            NSLog(@"手機水平,home鍵在左邊");
            break;
        case UIInterfaceOrientationLandscapeRight:
            NSLog(@"手機水平,home鍵在右邊");
            break;
        default:
            break;
    }
}

整體同理于方法2,但有一些區(qū)別。獲取到的方向是UIInterfaceOrientation,即界面方向,只有“上下左右”4個方向。

PS:[UIApplication sharedApplication].statusBarOrientation在iOS13之后會被廢棄掉,官方建議使用window的方向。即如下:
[UIApplication sharedApplication].windows.firstObject.windowScene.interfaceOrientation

但這個API也只能在iOS13之后才能使用。

參考文檔:

【1】IOS9開始如何處理轉(zhuǎn)屏

【2】UIApplication

【3】iOS開發(fā)之屏幕旋轉(zhuǎn)

?著作權(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ù)。

相關(guān)閱讀更多精彩內(nèi)容

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