有个很详细的博客可以看下基础部分
https://www.jianshu.com/p/e473749f1c30
本文是在Device Orientation只勾选Portrait基础上使用transform来设置视频全屏问题
先介绍一个设备方向改变的通知:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceOrientationChange) name:UIDeviceOrientationDidChangeNotification object:nil];
该方法会根据设备方向的改变触发。
注:
在注册通知前需要添加以下代码:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
文档上的定义是:
在尝试从接收器获取方向数据之前,必须调用此方法。 此方法启用设备的加速度计硬件,并开始向接收器传送加速度事件。 接收器随后使用这些事件在设备方向更改时发布UIDeviceOrientationDidChangeNotification通知并更新orientation属性。
可以安全地嵌套对此方法的调用,但是应该始终将每个调用与对endGeneratingDeviceOrientationNotifications方法的相应调用进行匹配。
因此,我们需要在dealloc方法中调用
[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
在通知方法里获取当前设备的方向。视屏播放考虑三个方向:UIInterfaceOrientationPortrait、UIInterfaceOrientationLandscapeLeft、UIInterfaceOrientationLandscapeRight,其他方向不考虑
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
// 未知、平放朝上、平放朝下、竖直home键朝上 不操作
if (deviceOrientation == UIDeviceOrientationUnknown || deviceOrientation == UIDeviceOrientationFaceUp || deviceOrientation == UIDeviceOrientationFaceDown || deviceOrientation == UIDeviceOrientationPortraitUpsideDown) {
return;
}
// UIDeviceOrientation转换为UIInterfaceOrientation是因为contrastOrientation:方法里进行转屏操作
UIInterfaceOrientation interfaceOrientation = (UIInterfaceOrientation)deviceOrientation;
switch (interfaceOrientation) {// 设备方向
case UIInterfaceOrientationPortrait://屏幕竖直
{
[self contrastOrientation:UIInterfaceOrientationPortrait];
}
break;
case UIInterfaceOrientationLandscapeLeft://屏幕左横
{
[self contrastOrientation:UIInterfaceOrientationLandscapeLeft];
}
break;
case UIInterfaceOrientationLandscapeRight://屏幕右横
{
[self contrastOrientation:UIInterfaceOrientationLandscapeRight];
}
break;
default:
break;
}
// 当前屏幕方向与设备方向(转化为UIInterfaceOrientation类型)对比操作
- (void)contrastOrientation:(UIInterfaceOrientation)orientation{
// 当前状态栏方向
UIInterfaceOrientation currentOrientation = [UIApplication sharedApplication].statusBarOrientation;
if (currentOrientation == orientation) return;// 一致
// 视频view约束+旋转
if (orientation == UIInterfaceOrientationPortrait) {
[self removeFromSuperview];
[_playModel.fatherView addSubview:self];
[self mas_remakeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.playModel.fatherView);
}];
} else if (orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight){
[self removeFromSuperview];
[APP_Window addSubview:self];
[self mas_remakeConstraints:^(MASConstraintMaker *make) {
make.center.equalTo(APP_Window);
make.width.equalTo(APP_Window.mas_height);
make.height.equalTo(APP_Window.mas_width);
}];
}
/**
* iOS6.0之后,设置状态条的方法能使用的前提是shouldAutorotate为NO,也就是说这个视图控制器内,旋转要关掉;
UIViewController+Rotation分类写好方法
*/
[[UIApplication sharedApplication] setStatusBarOrientation:orientation animated:NO];
[UIView animateWithDuration:0.25 animations:^{
self.transform = [self transformRotationAngle];
}];
}
// 旋转角度
- (CGAffineTransform)transformRotationAngle{
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
// 根据要进行旋转的方向来计算旋转的角度
if (orientation == UIInterfaceOrientationPortrait) {
return CGAffineTransformIdentity;
} else if (orientation == UIInterfaceOrientationLandscapeLeft){
return CGAffineTransformMakeRotation(-M_PI_2);
} else if(orientation == UIInterfaceOrientationLandscapeRight){
return CGAffineTransformMakeRotation(M_PI_2);
}
return CGAffineTransformIdentity;
}
这里有个[[UIApplication sharedApplication] setStatusBarOrientation:orientation animated:NO];,该方法是设置状态栏方向,但是iOS6.0以后有个限制条件——shouldAutorotate为NO,也就是说这个视图控制器内,旋转要关掉。
一般项目都有UITabBarController、UINavigationController、UIViewController,要修改当前ViewController的shouldAutorotate,必须在UITabBarController、UINavigationController里都要重写。
这里为了方便写了个category。(UIViewController是UINavigationController和UITabBarController父类,只要在UIViewController (Rotation)里重写shouldAutorotate可以达到效果)
UIViewController+Rotation.h
@interface UIViewController (Rotation)
@end
UIViewController+Rotation.m
@implementation UIViewController (Rotation)
// 是否支持自动转屏
- (BOOL)shouldAutorotate {
return NO;
}
// 支持哪些屏幕方向
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
// 默认的屏幕方向(当前ViewController必须是通过模态出来的UIViewController(模态带导航的无效)方式展现出来的,才会调用这个方法)
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationPortrait;
}
@end
这样的话,我们只需在Device Orientation只勾选Portrait就可以旋转屏幕了。
网友评论