iOS16橫豎屏的切換有了新的方式口蝠,正好趕上新的項(xiàng)目要求蚊夫,所以重新整理了一下項(xiàng)目中的橫豎屏切換問題。
項(xiàng)目要求:
- iPhone整體禁止屏幕旋轉(zhuǎn)只能豎屏孤里,某些特定頁面強(qiáng)制橫屏,某些頁面可以自由旋轉(zhuǎn)革为。
- iPad整體可以自由旋轉(zhuǎn)扭粱,某些頁面可以強(qiáng)制切換橫豎屏,且切換后當(dāng)前頁面關(guān)閉自由旋轉(zhuǎn)震檩,返回后開啟自由旋轉(zhuǎn)琢蛤。
如何開始橫豎屏切換
1、項(xiàng)目配置:
在Xcode中TARGETS - General - Deployment Info
中設(shè)置支持的方向抛虏,例如iPhone設(shè)置只支持豎屏博其,iPad支持全方向,注意iPad情況下需要勾選Requires full screen
迂猴,設(shè)置為全屏慕淡,不分屏,否則強(qiáng)制切換屏幕旋轉(zhuǎn)將失效(自己發(fā)現(xiàn)的沸毁,沒有找到相關(guān)解釋峰髓,有大神也可以解釋一下)。如果不配置息尺,只通過AppDelegate
中代理方法控制携兵,會(huì)導(dǎo)致啟動(dòng)頁時(shí)不能正常識(shí)別屏幕方向。
2搂誉、AppDelegate
中的設(shè)置
因?yàn)槟承╉撁嫘枰獜?qiáng)制屏幕切換徐紧,所以通過在AppDelegate
實(shí)現(xiàn)代理的方式控制.
AppDelegate.h
中
/// 通過AppDelegate是實(shí)現(xiàn)旋轉(zhuǎn),解決部分頁面強(qiáng)制旋轉(zhuǎn)
/// 屏幕支持的方法方向
@property (nonatomic, assign) UIInterfaceOrientationMask orientations;
AppDelegate.m
中
- 在
application:didFinishLaunchingWithOptions:
中設(shè)置默認(rèn)方向
// 設(shè)置默認(rèn)方向
if (isPad) {
// ipad
self.orientations = UIInterfaceOrientationMaskAll;
} else {
self.orientations = UIInterfaceOrientationMaskPortrait;
}
- 實(shí)現(xiàn)代理方法
/// 切換橫豎屏:返回支持方向
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
return self.orientations;
}
- 強(qiáng)制切換方向炭懊,且切換后禁止旋轉(zhuǎn)
例如強(qiáng)制橫屏如下
// AppDelegate設(shè)置橫屏
AppDelegate *app = (AppDelegate *)[UIApplication sharedApplication].delegate;
// 當(dāng)前是否橫屏
if ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationLandscapeLeft || [UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationLandscapeRight) {
// 已經(jīng)橫屏并级,AppDelegate中鎖定為當(dāng)前屏幕狀態(tài)
app.orientations = (1 << [UIApplication sharedApplication].statusBarOrientation);
} else {
// 豎屏-強(qiáng)制屏幕橫屏
// AppDelegate中鎖定為橫屏
app.orientations = UIInterfaceOrientationMaskLandscapeRight;
// 強(qiáng)制旋轉(zhuǎn)
if (@available(iOS 16.0, *)) {
#if defined(__IPHONE_16_0)
// 避免沒有更新Xcode14的同事報(bào)錯(cuò)
// iOS16新API,讓控制器刷新方向侮腹,新方向?yàn)樯厦嬖O(shè)置的orientations
[self setNeedsUpdateOfSupportedInterfaceOrientations];
#endif
} else {
// iOS16以下
NSNumber *orientationPortrait = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight];
[[UIDevice currentDevice] setValue:orientationPortrait forKey:@"orientation"];
}
}
在適當(dāng)?shù)奈恢糜浀胕Phone修正方向嘲碧,iPad放開旋轉(zhuǎn)
// iPhone改為豎屏,具體方式參考橫屏
// pad放開屏幕方向
AppDelegate *app = (AppDelegate *)[UIApplication sharedApplication].delegate;
app.orientations = UIInterfaceOrientationMaskAll;
- 某個(gè)頁面放開橫豎屏切換凯旋,比如全屏視頻播放時(shí)呀潭。
// 放開
AppDelegate *app = (AppDelegate *)[UIApplication sharedApplication].delegate;
app.orientations = UIInterfaceOrientationMaskAll;
// 鎖定
AppDelegate *app = (AppDelegate *)[UIApplication sharedApplication].delegate;
app.orientations = UIInterfaceOrientationMaskPortrait;
#這種情況下钉迷,iOS16的強(qiáng)制橫豎屏切換需要添加代碼設(shè)置強(qiáng)制旋轉(zhuǎn),例如:
// 強(qiáng)制屏幕豎屏:手機(jī)
if ([UIApplication sharedApplication].statusBarOrientation != UIInterfaceOrientationPortrait) {
if (@available(iOS 16.0, *)) {
// iOS16新API钠署,讓控制器刷新方向糠聪,新方向?yàn)樯厦嬖O(shè)置的orientations
#if defined(__IPHONE_16_0)
[self setNeedsUpdateOfSupportedInterfaceOrientations];
NSArray *array = [[[UIApplication sharedApplication] connectedScenes] allObjects];
UIWindowScene *scene = [array firstObject];
// 屏幕方向
UIInterfaceOrientationMask orientation = UIInterfaceOrientationMaskPortrait;
UIWindowSceneGeometryPreferencesIOS *geometryPreferencesIOS = [[UIWindowSceneGeometryPreferencesIOS alloc] initWithInterfaceOrientations:orientation];
// 開始切換
[scene requestGeometryUpdateWithPreferences:geometryPreferencesIOS errorHandler:^(NSError * _Nonnull error) {
NSLog(@"強(qiáng)制%@錯(cuò)誤:%@", @"橫屏", error);
}];
#endif
} else {
// iOS16以下
NSNumber *orientationPortrait = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
[[UIDevice currentDevice] setValue:orientationPortrait forKey:@"orientation"];
}
}
- 關(guān)于橫豎屏切換的監(jiān)聽
對(duì)于屏幕旋轉(zhuǎn)的監(jiān)聽,建議監(jiān)聽UIApplicationDidChangeStatusBarOrientationNotification
谐鼎,及狀態(tài)欄的方向變化通知舰蟆,這個(gè)收到這個(gè)通知的時(shí)候說明頁面UI已經(jīng)切換了。例如:
// 橫豎屏切換通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleScreenOrientationChange:) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];
/// 橫豎屏切換通知
- (void)handleScreenOrientationChange:(NSNotification *)noti {
if ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortrait || [UIApplication sharedApplication].statusBarOrientation == UIDeviceOrientationPortraitUpsideDown) {
// 豎屏
} else {
// 橫屏
}
}
注意判斷屏幕方向的時(shí)候一定要用UIInterfaceOrientation:屏幕的方向狸棍,不要錯(cuò)誤的使用的UIDeviceOrientation:設(shè)備的方向身害。
暫時(shí)就這些內(nèi)容。
補(bǔ)充一點(diǎn)草戈,寫代碼的時(shí)候能用Autolayout就盡量用塌鸯,不然突然有一天讓你整個(gè)App適配橫豎屏切換,在原有手機(jī)端代碼基礎(chǔ)上開發(fā)Pad唐片,還有分屏效果丙猬,哭都沒地方。