背景
iOS16之前转屏方法, 16之后无效, 导致界面错乱.
虽然Xcode14/iOS16提供了新的api但还是beta版, 不能直接打包上线, 所以要在旧版适配新版本.
怎么适配 尝试了很多方法, 比如横屏时直接present一个横屏VC, 但耗时耗力, 怎么花最小代价适配iOS16, 看下面...
未升级Xcode14提前调试iOS16
下载iOS16系统支持包
放到这个件夹下, 重启Xcode就可以了
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport
iOS16新增转屏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 转屏Error: %@",error);
}];
但在升级xcode14之前不能直接调用到, 可以通过获取方法IMP调用
所以可以先这么适配, 上代码:
+ (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方法不调用
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 转屏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 {
}
}
欢迎大佬评论交流👍🏻
网友评论