屏幕的横竖屏适配有很多种,今天写直播demo的时候发现给播放器一套约束或者frame,自动切换横屏的时候布局混乱拉伸。
这第一种方法,直接监听横竖屏切换,然后改变布局代码,纯代码布局基本都是这个思路。
/** 注册屏幕横竖通知 */
//开启和监听 设备旋转的通知(不开启的话,设备方向一直是UIInterfaceOrientationUnknown)
if (![UIDevice currentDevice].generatesDeviceOrientationNotifications) {
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
}
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(handleDeviceOrientationChange:)
name:UIDeviceOrientationDidChangeNotification object:nil];
/** 通知事件处理 */
//设备方向改变的处理
- (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(@"屏幕向左横置");
//以左横为例,改变frame的话可以加动画,也可以用masonry处理(mas_remake),视情况选择,一般来说不需要每种情况都处理,左横右横直立三种就差不多了。
[UIView animateWithDuration:1.0 animations:^{
_player.view.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
}];
[_player.view mas_remakeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(0);
make.left.mas_equalTo(0);
make.size.mas_equalTo(CGSizeMake([UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height));
}];
}
break;
case UIDeviceOrientationLandscapeRight:
NSLog(@"屏幕向右橫置");
break;
case UIDeviceOrientationPortrait:
NSLog(@"屏幕直立");
break;
case UIDeviceOrientationPortraitUpsideDown:
NSLog(@"屏幕直立,上下顛倒");
break;
default:
NSLog(@"无法辨识");
break;
}
}
/** 最后在dealloc中移除通知 和结束设备旋转的通知 */
- (void)dealloc{
//...
[[NSNotificationCenter defaultCenter]removeObserver:self];
[[UIDevice currentDevice]endGeneratingDeviceOrientationNotifications];
}
/** 提示一下,需要记住以下几种方法,这些方法都是tabbar navigation viewcontroller 层层传递,具体使用另行查阅资料*/
- (BOOL)shouldAutorotate{
//是否自动旋转,返回YES可以自动旋转,返回NO禁止旋转
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations{
//返回支持的方向
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
//由模态推出的视图控制器 优先支持的屏幕方向
}
第二种就是xib创建的视图,Trait Variations其实就是iOS8.0之后取代sizeClass而已,具体的东西得自己去研究。
拖入控件后,勾上此处的width,然后开始布局添加约束,添加完之后点击Down Varying,此间添加的所有约束就只针对竖屏生效,反之点击height,约束就对横屏生效。
image.png
image.png
第三种,还是xib,针对一个约束添加多个不同优先级的约束,把约束关联到代码里面,然后跟第一种方法一样监听横屏,再把约束的优先级更改,便可使相应优先级的约束生效(默认第一优先级1000生效),如图默认约束为60,49为次优先级,可在代码中使其生效。
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *testConstraint;
_testConstraint.priority = UILayoutPriorityDefaultLow;
image.png
第四种,随便提一下就行,在我看来也就是sizeClass和第二种一样的,如下图,竖屏状态是wC:hR 横屏下是wC:hC (w是width h是height,C是Compact R是Regular) ,可以针对横屏和竖屏分别添加或修改约束值。
注意:不管是第二种还是第四种,如果在拖入控件之前就限制了方向,那么你就会发现切换到另一种方向的时候此控件是不存在的。只有拖入控件时installed选中或者第二种没有操作,才会两种状态都存在控件,运行也是一样的效果。具体操作坑还是比较多的,所以需要自己去实践,这里只提供一个思路。
image.png