谈谈iOS中的屏幕方向

时间:2022-12-02 15:52:02

众所周知,iOS中提供了[UIDevice currentDevice].orientation与[UIApplication sharedApplication].statusBarOrientation这两种方式来获取设备的屏幕方向。

其中UIDeviceOrientation包括以下几种枚举值

typedef NS_ENUM(NSInteger, UIDeviceOrientation) {
UIDeviceOrientationUnknown,
UIDeviceOrientationPortrait, // Device oriented vertically, home button on the bottom
UIDeviceOrientationPortraitUpsideDown, // Device oriented vertically, home button on the top
UIDeviceOrientationLandscapeLeft, // Device oriented horizontally, home button on the right
UIDeviceOrientationLandscapeRight, // Device oriented horizontally, home button on the left
UIDeviceOrientationFaceUp, // Device oriented flat, face up
UIDeviceOrientationFaceDown // Device oriented flat, face down
} __TVOS_PROHIBITED;

其中UIInterfaceOrientation包括以下几种枚举值

typedef NS_ENUM(NSInteger, UIInterfaceOrientation) {
UIInterfaceOrientationUnknown = UIDeviceOrientationUnknown,
UIInterfaceOrientationPortrait = UIDeviceOrientationPortrait,
UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown,
UIInterfaceOrientationLandscapeLeft = UIDeviceOrientationLandscapeRight,
UIInterfaceOrientationLandscapeRight = UIDeviceOrientationLandscapeLeft
} __TVOS_PROHIBITED;

可以看出UIInterfaceOrientation本质其实就是UIDeviceOrientation,但是这不是重点,说说我最近遇到的坑吧。

首先外部是一个tableview的列表页,cell里面有视频可以播,需求是列表页不需要重力感应,也就说一直保持垂直方向,但是cell中的视频点开后需要全屏,这个视频是要有重力感应的。

这时会出现一个问题,如果我手机保持横屏,第一次进入视频,视频并不会改变方向,并且UIDeviceOrientation打印出来为UIDeviceOrientationPortrait,因为我在视频的controller里才beginGeneratingDeviceOrientationNotifications,[UIDevice currentDevice].orientation在没有遇到方向改变的时候,他是不会更新状态的!!!所以就造成了与实际方向不符的情况。而父页面,也就是列表页的UIInterfaceOrientation始终垂直,所以[UIApplication sharedApplication].statusBarOrientation也是用不了的,肿么办!!!

于是乎,别人推荐了CMMotionManager来对方向进行判断,CMMotionManager是从属于Core Motion框架,利用iPhone上的重力加速计芯片来捕捉手机的各种加速值。

代码如下:

- (void)initializeMotionManager{
motionManager = [[CMMotionManager alloc] init];
motionManager.accelerometerUpdateInterval = .;
motionManager.gyroUpdateInterval = .; [motionManager startAccelerometerUpdatesToQueue:[NSOperationQueue currentQueue]
withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) {
if (!error) {
[self outputAccelertionData:accelerometerData.acceleration];
}
else{
NSLog(@"%@", error);
}
}];
}
- (void)outputAccelertionData:(CMAcceleration)acceleration{
UIInterfaceOrientation orientationNew; if (acceleration.x >= 0.75) {
orientationNew = UIInterfaceOrientationLandscapeLeft;
}
else if (acceleration.x <= -0.75) {
orientationNew = UIInterfaceOrientationLandscapeRight;
}
else if (acceleration.y <= -0.75) {
orientationNew = UIInterfaceOrientationPortrait;
}
else if (acceleration.y >= 0.75) {
orientationNew = UIInterfaceOrientationPortraitUpsideDown;
}
else {
// Consider same as last time
return;
} if (orientationNew == orientationLast)
return; orientationLast = orientationNew;
}

这样就可以实时的获得当前设备的方向啦