背景
iOS16之前轉(zhuǎn)屏方法setOrientation:
, 16之后使用無效.
雖然Xcode14/iOS16提供了新的api但還是beta版, 不能直接打包上線, 所以要在舊版適配新版本.
怎么適配 嘗試了很多方法, 比如橫屏?xí)r直接present一個(gè)橫屏VC, 但耗時(shí)耗力, 怎么花最小代價(jià)適配iOS16, 看下面...
未升級Xcode14提前調(diào)試iOS16
下載iOS16系統(tǒng)支持包
放到這個(gè)件夾下, 重啟Xcode就可以了
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport
iOS16新增轉(zhuǎn)屏api
UINavigationController *nav = [TYToolsUtil topViewController].navigationController;
[nav setNeedsUpdateOfSupportedInterfaceOrientations];
NSArray *array = [[[UIApplication sharedApplication] connectedScenes] allObjects];
UIWindowScene *ws = (UIWindowScene *)array.firstObject;
UIWindowSceneGeometryPreferencesIOS *geometryPreferences = [[UIWindowSceneGeometryPreferencesIOS alloc] init];
geometryPreferences.interfaceOrientations = UIInterfaceOrientationMaskLandscapeRight;
[ws requestGeometryUpdateWithPreferences:geometryPreferences
errorHandler:^(NSError * _Nonnull error) {
NSLog(@"iOS 16 轉(zhuǎn)屏Error: %@",error);
}];
但在升級xcode14之前不能直接調(diào)用到, 可以通過獲取方法IMP調(diào)用
所以可以先這么適配, 上代碼:
+ (void)setDevOri:(UIDeviceOrientation)ori {
@try {
// ios16使用新的api
if (@available(iOS 16.0, *)) {
UIInterfaceOrientationMask oriMask = UIInterfaceOrientationMaskPortrait;
if (ori == UIDeviceOrientationPortrait) {
oriMask = UIInterfaceOrientationMaskPortrait;
} else if (ori == UIDeviceOrientationLandscapeLeft) {
oriMask = UIInterfaceOrientationMaskLandscapeRight;
} else if (ori == UIDeviceOrientationLandscapeRight) {
oriMask = UIInterfaceOrientationMaskLandscapeLeft;
} else {
return;
}
// 防止appDelegate supportedInterfaceOrientationsForWindow方法不調(diào)用
UINavigationController *nav = [TYToolsUtil topViewController].navigationController;
SEL selUpdateSupportedMethod = NSSelectorFromString(@"setNeedsUpdateOfSupportedInterfaceOrientations");
if ([nav respondsToSelector:selUpdateSupportedMethod]) {
(((void (*)(id, SEL))[nav methodForSelector:selUpdateSupportedMethod])(nav, selUpdateSupportedMethod));
}
NSArray *array = [[[UIApplication sharedApplication] connectedScenes] allObjects];
UIWindowScene *ws = (UIWindowScene *)array.firstObject;
Class GeometryPreferences = NSClassFromString(@"UIWindowSceneGeometryPreferencesIOS");
id geometryPreferences = [[GeometryPreferences alloc] init];
[geometryPreferences setValue:@(oriMask) forKey:@"interfaceOrientations"];
SEL selGeometryUpdateMethod = NSSelectorFromString(@"requestGeometryUpdateWithPreferences:errorHandler:");
void (^ErrorBlock)(NSError *error) = ^(NSError *error){
NSLog(@"iOS 16 轉(zhuǎn)屏Error: %@",error);
};
if ([ws respondsToSelector:selGeometryUpdateMethod]) {
(((void (*)(id, SEL,id,id))[ws methodForSelector:selGeometryUpdateMethod])(ws, selGeometryUpdateMethod,geometryPreferences,ErrorBlock));
}
} else {
if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) {
SEL selector = NSSelectorFromString(@"setOrientation:");
if ([UIDevice currentDevice].orientation == ori) {
NSInvocation *invocationUnknow = [NSInvocation invocationWithMethodSignature:[UIDevice instanceMethodSignatureForSelector:selector]];
[invocationUnknow setSelector:selector];
[invocationUnknow setTarget:[UIDevice currentDevice]];
UIDeviceOrientation unKnowVal = UIDeviceOrientationUnknown;
[invocationUnknow setArgument:&unKnowVal atIndex:2];
[invocationUnknow invoke];
}
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDevice instanceMethodSignatureForSelector:selector]];
[invocation setSelector:selector];
[invocation setTarget:[UIDevice currentDevice]];
UIDeviceOrientation val = ori;
[invocation setArgument:&val atIndex:2];
[invocation invoke];
}
}
} @catch (NSException *exception) {
} @finally {
}
}
注意: 使用iOS16方法, 調(diào)轉(zhuǎn)屏方法后立即處理UI, 可能造成界面錯(cuò)亂.
歡迎大佬評論交流????