转屏主要分为两种方式来实现:
第一种是物理转屏(强制转屏),这种方式的优点是子视图无需再次更新位置布局,能跟着父视图适应了对应的位置,另外状态栏也能跟着转过来了。缺点是返回竖排模式时有种转屏时的视觉冲击感!还有某些其他的比如table自动位移的坑!用户体验不算完美。值得提醒的是:坐标系发生了改变,宽度的最大值变成了高度。
核心代码如下:
//添加到Window上
UIWindow *keyWindow = [UIApplication sharedApplication].delegate.window;
[keyWindow addSubview:self];
[[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIInterfaceOrientationLandscapeRight] forKey:@"orientation"];
self.frame = CGRectMake(0, 0, MAX([UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height), MIN([UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height));
第二种动画转屏,使用仿射变换CGAffineTransform,这种方式状态栏不能转过来,看新浪微博的做法是隐藏了状态栏。
其优点:没有特别的副作用,不全局影响整个app的其他控制器,坐标系没有发生变化。
缺点(痛点)1、转屏后需要更新子视图的的坐标位置(前提是使用Frame布局),导致代码量增加,恢复竖排又需要更新子视图的的坐标位置;2、状态栏还是处于竖排状态,方向不能改变,因为苹果提供的相关方法setStatusBarOrientation已经弃用了。
代码实现如下:
#pragma mark全屏
- (void)fullScreen{
//添加到Window上
[_coverIV removeFromSuperview];
UIWindow *keyWindow = [UIApplication sharedApplication].delegate.window;
[keyWindow addSubview:_coverIV];
CGFloat duration = [UIApplication sharedApplication].statusBarOrientationAnimationDuration;
// [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:YES];
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];
[UIView animateWithDuration:duration animations:^{
self.coverIV.transform = CGAffineTransformMakeRotation(M_PI / 2);
}];
self.coverIV.frame=CGRectMake(0,0,MIN([UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height),MAX([UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height));
//接着修改coverIV的子视图坐标位置
}
那可能某些朋友会问:你为什么不使用masonry自动布局?其实我一开始是使用Masonry布局视频控件的,使用masonry自动布局的好处是:设置子视图布局的代码在layoutSubview中刷新可以复用子视图的布局代码。
至少在ios12、13中运行没有问题,但是偏偏ios10出了问题,我暂时没解决,所以改成了Frame形式来兼容所有的系统,这个自动布局苹果还是有一些坑的。
或许还有第三种转场动画跳转到一个新的控制器来转屏实现,甚至第四种等方案...?
大家如果有完美的解决方式可以讨论一下!
最后转屏给点重点提示:记得设置支持的方向
//支持的方向
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskAllButUpsideDown;//注意一定要使用这个枚举
}
- (BOOL)shouldAutorotate{
return YES;
}
网友评论