屏幕的橫豎屏適配有很多種,今天寫直播demo的時(shí)候發(fā)現(xiàn)給播放器一套約束或者frame,自動(dòng)切換橫屏的時(shí)候布局混亂拉伸。
這第一種方法,直接監(jiān)聽橫豎屏切換,然后改變布局代碼,純代碼布局基本都是這個(gè)思路。
/** 注冊(cè)屏幕橫豎通知 */
//開啟和監(jiān)聽 設(shè)備旋轉(zhuǎn)的通知(不開啟的話,設(shè)備方向一直是UIInterfaceOrientationUnknown)
if (![UIDevice currentDevice].generatesDeviceOrientationNotifications) {
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
}
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(handleDeviceOrientationChange:)
name:UIDeviceOrientationDidChangeNotification object:nil];
/** 通知事件處理 */
//設(shè)備方向改變的處理
- (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的話可以加動(dòng)畫,也可以用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(@"無法辨識(shí)");
break;
}
}
/** 最后在dealloc中移除通知 和結(jié)束設(shè)備旋轉(zhuǎn)的通知 */
- (void)dealloc{
//...
[[NSNotificationCenter defaultCenter]removeObserver:self];
[[UIDevice currentDevice]endGeneratingDeviceOrientationNotifications];
}
/** 提示一下,需要記住以下幾種方法,這些方法都是tabbar navigation viewcontroller 層層傳遞,具體使用另行查閱資料*/
- (BOOL)shouldAutorotate{
//是否自動(dòng)旋轉(zhuǎn),返回YES可以自動(dòng)旋轉(zhuǎn),返回NO禁止旋轉(zhuǎn)
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations{
//返回支持的方向
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
//由模態(tài)推出的視圖控制器 優(yōu)先支持的屏幕方向
}
第二種就是xib創(chuàng)建的視圖,Trait Variations其實(shí)就是iOS8.0之后取代sizeClass而已,具體的東西得自己去研究。
拖入控件后,勾上此處的width,然后開始布局添加約束,添加完之后點(diǎn)擊Down Varying,此間添加的所有約束就只針對(duì)豎屏生效,反之點(diǎn)擊height,約束就對(duì)橫屏生效。

image.png

image.png
第三種,還是xib,針對(duì)一個(gè)約束添加多個(gè)不同優(yōu)先級(jí)的約束,把約束關(guān)聯(lián)到代碼里面,然后跟第一種方法一樣監(jiān)聽橫屏,再把約束的優(yōu)先級(jí)更改,便可使相應(yīng)優(yōu)先級(jí)的約束生效(默認(rèn)第一優(yōu)先級(jí)1000生效),如圖默認(rèn)約束為60,49為次優(yōu)先級(jí),可在代碼中使其生效。
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *testConstraint;
_testConstraint.priority = UILayoutPriorityDefaultLow;

image.png
第四種,隨便提一下就行,在我看來也就是sizeClass和第二種一樣的,如下圖,豎屏狀態(tài)是wC:hR 橫屏下是wC:hC (w是width h是height,C是Compact R是Regular) ,可以針對(duì)橫屏和豎屏分別添加或修改約束值。
注意:不管是第二種還是第四種,如果在拖入控件之前就限制了方向,那么你就會(huì)發(fā)現(xiàn)切換到另一種方向的時(shí)候此控件是不存在的。只有拖入控件時(shí)installed選中或者第二種沒有操作,才會(huì)兩種狀態(tài)都存在控件,運(yùn)行也是一樣的效果。具體操作坑還是比較多的,所以需要自己去實(shí)踐,這里只提供一個(gè)思路。

image.png