UIDeviceOrientation 设备方向 & UIInterfaceOrientation 控制器方向

    为什么写这篇博客呢,因为在封装播放器avplayer的过程中,横屏竖屏的旋转让我纠结了好一会,写的明明是正确的,就是因为Xcode有没有勾选横屏出现了旋转问题,小细节决定大问题呀。


接下来细说 UIDeviceOrientation 和 UIInterfaceOrientation 的区别与联系


一、UIDeviceOrientation设备方向

UIDeviceOrientation设备方向,也就是苹果手机的旋转方向。


1)iOS定义了以下七种设备方向

typedef NS_ENUM(NSInteger, UIDeviceOrientation) {
    UIDeviceOrientationUnknown,                   // 未知方向,可能是设备(屏幕)斜置
    UIDeviceOrientationPortrait,                     // 设备(屏幕)直立
    UIDeviceOrientationPortraitUpsideDown,    // 设备(屏幕)直立,上下顛倒
    UIDeviceOrientationLandscapeLeft,           // 设备(屏幕)向左横置
    UIDeviceOrientationLandscapeRight,         // 设备(屏幕)向右橫置
    UIDeviceOrientationFaceUp,                     // 设备(屏幕)朝上平躺    

UIDeviceOrientationFaceDown                      // 设备(屏幕)朝下平躺

} __TVOS_PROHIBITED;

说明:UIDeviceOrientation参考home键方向,

如:home方向在右,设备(屏幕)方向向左(UIDeviceOrientationLandscapeLeft)


2)读取设备方向

UIDevice单例代表当前的设备。从这个单例中可以获得的信息设备,如设备方向orientation。

UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;

3)获取旋转所用的时间

获取UIDevice手机设备旋转的时间,写横屏竖屏的时间旋转时间更加自然流畅

CGFloat duration = [UIApplication sharedApplication].statusBarOrientationAnimationDuration;


4)设备方向改变的通知

当设备方向变化时候,发出UIDeviceOrientationDidChangeNotification通知;注册监听该通知,可以针对不同的设备方向处理视图展示。

开启和监听 设备旋转的通知(不开启的话,设备方向一直是UIInterfaceOrientationUnknown,这个一定要注意)

if (![UIDevice currentDevice].generatesDeviceOrientationNotifications) {
    [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
}
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(handleDeviceOrientationChange:) 
                                     name:UIDeviceOrientationDidChangeNotification object:[UIDevice currentDevice]];

设备方向改变的处理

- (void)handleDeviceOrientationChange:(NSNotification *)notification{


    UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
    switch (ddeviceOrientation) {
        case UIDeviceOrientationFaceUp:
            NSLog(@"屏幕朝上平躺");
            break;
        
        case UIDeviceOrientationFaceDown:
            NSLog(@"屏幕朝下平躺");
            break;
        
        case UIDeviceOrientationUnknown:
            NSLog(@"未知方向");
            break;
        
        case UIDeviceOrientationLandscapeLeft:
            NSLog(@"屏幕向左横置");
            break;
        
        case UIDeviceOrientationLandscapeRight:
            NSLog(@"屏幕向右橫置");
            break;
        
        case UIDeviceOrientationPortrait:
            NSLog(@"屏幕直立");
            break;
        
        case UIDeviceOrientationPortraitUpsideDown:
            NSLog(@"屏幕直立,上下顛倒");
            break;
        
        default:
            NSLog(@"无法辨识");
            break;
    }
}


最后在dealloc中移除通知 和结束设备旋转的通知 一定要移除,不然会造成内存泄漏

- (void)dealloc{
    //...
[[UIDevice currentDevice]endGeneratingDeviceOrientationNotifications];
    [[NSNotificationCenter defaultCenter]removeObserver:self];
}

注意:手机锁定竖屏后,UIDeviceOrientationDidChangeNotification通知就失效了。




二、UIInterfaceOrientation:控制器方向

控制器方向是反应iOS中界面的方向,它和Home按钮的方向是一致的。

1)iOS定义了以下五种界面方向

说明:从定义可知,界面方向和设别方向有对应关系,
如界面的竖直方向就是 :UIInterfaceOrientationUnknown = UIDeviceOrientationUnknown
typedef NS_ENUM(NSInteger, UIInterfaceOrientation) {
    UIInterfaceOrientationUnknown            = UIDeviceOrientationUnknown,       //未知方向
    UIInterfaceOrientationPortrait           = UIDeviceOrientationPortrait,               //界面直立
    UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown,  //界面直立,上下颠倒
    UIInterfaceOrientationLandscapeLeft      = UIDeviceOrientationLandscapeRight,   //界面朝左
    UIInterfaceOrientationLandscapeRight     = UIDeviceOrientationLandscapeLeft    //界面朝右
} __TVOS_PROHIBITED;


2)读取界面方向

UIInterfaceOrientation和状态栏有关,通过UIApplication的单例调用statusBarOrientation来获取

UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation];


3)界面方向改变的通知

当界面方向变化时候,先后发出

UIApplicationWillChangeStatusBarOrientationNotification 和 UIApplicationDidChangeStatusBarOrientationNotification

通知;注册监听这两个通知,可以针对不同的界面方向处理视图展示。

//以监听UIApplicationDidChangeStatusBarOrientationNotification通知为例

[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(handleStatusBarOrientationChange:) 
                                     name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];


//界面方向改变的处理
- (void)handleStatusBarOrientationChange: (NSNotification *)notification{

    UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation];
    switch (interfaceOrientation) {
        
        case UIInterfaceOrientationUnknown:
            NSLog(@"未知方向");
            break;
        
        case UIInterfaceOrientationPortrait:
            NSLog(@"界面直立");
            break;
        
        case UIInterfaceOrientationPortraitUpsideDown:
            NSLog(@"界面直立,上下颠倒");
            break;
        
        case UIInterfaceOrientationLandscapeLeft:
            NSLog(@"界面朝左");
            break;
        
        case UIInterfaceOrientationLandscapeRight:
            NSLog(@"界面朝右");
            break;
    
        default:
            break;
    }
}

//最后在dealloc中移除通知
- (void)dealloc{
    //...
    [[NSNotificationCenter defaultCenter]removeObserver:self];
    [[UIDevice currentDevice]endGeneratingDeviceOrientationNotifications];
}


说明:手机锁定竖屏后,

UIApplicationWillChangeStatusBarOrientationNotification 和 UIApplicationDidChangeStatusBarOrientationNotification

通知也失效了。


三、Xcode中设置的方向

          如果在项目的General-->Deployment Info-->Device Orientation中,只勾选Portrait(竖屏),这个时候如果手机设备不锁屏的话控制器方向只返回UIInterfaceOrientationPortrait(竖屏方向)



如果勾选下面横屏的话,手机设备锁屏的时候,通知都会失效,如果手机没有锁屏,通知都存在,控制器方向一样跟着变,只是两种方向是相反的,处理的时候注意。



推荐:Github地址:  https://github.com/shuilanjianyue/SCHPlayer  

播放器的学习,这里更能体现屏幕旋转问题


猜你喜欢

转载自blog.csdn.net/sun_cui_hua/article/details/79771300