iOS_适配 iOS16 转屏

2023-10-27

iOS_适配 iOS16 转屏

  • 问题1:iOS 16 屏幕旋转报错:[Orientation] BUG IN CLIENT OF UIKIT: Setting UIDevice.orientation is not supported. Please use UIWindowScene.requestGeometryUpdate(_:)
    解决:iOS16 UIDevice 不再支持 setValue 方法,使用 UIWindowScenerequestGeometryUpdate() 的方法代替

  • 问题2: Xcode13Xcode14 编译出的安装包效果不一致
    解决:需要区分编译环境,写两套代码

  • 问题3:- (BOOL)shouldAutorotate{} 在iOS 16 已经不起作用了,无论返回 yes or no 都能转屏。
    解决:iOS16 新增:setNeedsUpdateOfSupportedInterfaceOrientations方法,用于通知 UIViewController 支持的屏幕方向有更新。在修改完 - (UIInterfaceOrientationMask)supportedInterfaceOrientations方法后调用

  • 问题4:iOS 16 转屏后立即获取的设备方向不正确:[UIDevice currentDevice].orientation 返回 UIDeviceOrientationUnknown
    解决:延迟回调 complete 后获取


Codes:

NSString *MODeviceOrientationDescription(UIDeviceOrientation orientation) {
    switch (orientation) {
        case UIDeviceOrientationUnknown: return @"Unknown";
        case UIDeviceOrientationPortrait: return @"Portrait";
        case UIDeviceOrientationPortraitUpsideDown: return @"PortraitUpsideDown";
        case UIDeviceOrientationLandscapeLeft: return @"LandscapeLeft";
        case UIDeviceOrientationLandscapeRight: return @"LandscapeRight";
        case UIDeviceOrientationFaceUp: return @"FaceUp";
        case UIDeviceOrientationFaceDown: return @"FaceDown";
    }
}

NSString *MOInterfaceOrientationDescription(UIInterfaceOrientation orientation) {
    switch (orientation) {
        case UIInterfaceOrientationUnknown: return @"Unknown";
        case UIInterfaceOrientationPortrait: return @"Portrait";
        case UIInterfaceOrientationPortraitUpsideDown: return @"PortraitUpsideDown";
        case UIInterfaceOrientationLandscapeLeft: return @"LandscapeLeft";
        case UIInterfaceOrientationLandscapeRight: return @"LandscapeRight";
    }
}

typedef void(^MODeviceOrientationCompletion)(NSError * _Nullable error);

void MOGeometryUpdate(UIViewController *viewController,
                      UIDeviceOrientation orientation,
                      MODeviceOrientationCompletion completion) {
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 160000
    /* Preprocess macro for compiling on Xcode14 */
    if (@available(iOS 16.0, *)) {
        if (![viewController respondsToSelector:@selector(setNeedsUpdateOfSupportedInterfaceOrientations)]) {
            NSString *errMsg = @"viewController can't respond setNeedsUpdateOfSupportedInterfaceOrientations";
            if (completion) {
                completion([NSError errorWithDomain:@"MODemo" code:0 userInfo:@{NSLocalizedDescriptionKey: errMsg}]);
            }
            return;
        }
        [viewController setNeedsUpdateOfSupportedInterfaceOrientations];
        [viewController.navigationController setNeedsUpdateOfSupportedInterfaceOrientations];
        
        // find scene
        NSArray<UIScene *> *scenes = [[[UIApplication sharedApplication] connectedScenes] allObjects];
        __block UIScene *firstScene = scenes.firstObject;
        [scenes enumerateObjectsUsingBlock:^(UIScene * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            // 转屏需要使用 role = UIWindowSceneSessionRoleApplication 的Scene,当取到其他Scene时,会转屏失败
            if ([obj.session.role isEqualToString:UIWindowSceneSessionRoleApplication]) {
                firstScene = obj;
                *stop = YES;
            }
        }];
        if (![firstScene isKindOfClass:[UIWindowScene class]]) {
            NSString *errMsg = [NSString stringWithFormat:@"Unexpected first scene, scenes: %@", scenes];
            if (completion) {
                completion([NSError errorWithDomain:@"MODemo" code:0 userInfo:@{NSLocalizedDescriptionKey: errMsg}]);
            }
            return;
        }
        UIWindowScene *windowScene = (UIWindowScene *)firstScene;
        UIInterfaceOrientationMask mask = 1 << orientation;
        UIWindowSceneGeometryPreferencesIOS *preferences = [[UIWindowSceneGeometryPreferencesIOS alloc] initWithInterfaceOrientations:mask];
        __block NSError *err = nil;
        [windowScene requestGeometryUpdateWithPreferences:preferences errorHandler:^(NSError * _Nonnull error) {
            NSString *errMsg = [NSString stringWithFormat:@"request geometry error: %@", error];
            err = [NSError errorWithDomain:@"MODemo" code:0 userInfo:@{NSLocalizedDescriptionKey: errMsg}];
            if (completion) {
                completion(error);
            }
        }];
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            if (completion) {
                completion(err);
            }
        });
    } else {
        [[UIDevice currentDevice] setValue:@(orientation) forKey:@"orientation"];
        [UIViewController attemptRotationToDeviceOrientation];
        if (completion) {
            completion(nil);
        }
    }
#else
    /* Preprocess macro for compiling on Xcode13 */
    [[UIDevice currentDevice] setValue:@(orientation) forKey:@"orientation"];
    [UIViewController attemptRotationToDeviceOrientation];
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        if (completion) {
            completion(nil);
        }
    });
#endif
}

github Demo


Reference:
Apple Developer Document
iOS 16适配屏幕旋转强制转屏切换大总结

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

iOS_适配 iOS16 转屏 的相关文章

  • 如何等待 webViewDidFinishLoad 完成

    我有一个初始化 webView 的布尔条件 并在 webViewDidFinishLoad 中加载另一个委托 以便在完成完成后触发 但是 由于布尔值在条件 webViewDidFinishLoad 之前返回 因此页面永远不会完全加载 如何确
  • 使用 Objective-C 在 iPhone 应用程序中显示或隐藏 UIButton

    我在用UITextView编辑文本 我想用两个UIButtons编辑并保存 最初我想显示编辑UIButton 当用户单击编辑时我想显示保存UIButton 当内容成功保存后 我不想再显示保存按钮 我是一名 C 编码员 在 C 中我曾经这样做
  • 使用 UIActionSheet 更改视图时工具栏项目消失

    当从 a 启动视图时UIActionSheet按钮 通过导航栏后退按钮返回视图后 工具栏虽然仍然可见 但上面没有任何以前的按钮 自从更新到 iOS 6 以来 这个错误就出现了 并且是在模拟器和仅运行 iOS 6 的设备上测试时发生的 如果我
  • 自动布局和ios5

    我正在使用故事板 我已经使用了自动布局 但它不适用于 ios5 并且会崩溃 所以我想删除它 但是 如何取消选中自动布局 但如果我取消选中自动布局 我如何为 iPhone 4 和 5 设置屏幕 Regards 您可以在 IB 中禁用自动布局
  • WebGL iOS 渲染为浮点纹理

    我正在尝试在 iOS Safari 上的 WebGL 中渲染浮点纹理 而不是在本机应用程序中 我已经设法让 iOS 读取手动 例如从 JavaScript 创建的浮点纹理 但是当我创建浮点类型的帧缓冲区并使用 GPU 渲染到其中时 它不起作
  • Swift:从自定义 UITableViewCell 中的 UITextField 检索文本并将其放入数组中

    我正在制作一个非常简单的应用程序 用户在第一个屏幕中输入人数 在第二个屏幕中 它会生成一些UITableViewCell基于用户在第一个屏幕中输入的数字 这UITableViewCell have a UITextField在其中 一旦用户
  • iOS 中的等宽字体是什么?

    我想要在我的 iOS 应用程序中为 UILabel 使用等宽字体 不幸的是 我找不到一个 甚至 美国打字机 实际上也不是等宽的 XCode 中可用的等宽字体是什么 iOS 等宽字体 Courier Courier Bold Courier
  • 如何将十六进制数组转换为 UIImage?

    有几个与使用 P25mi 动态打印图像相关的未解答问题 没有一个得到公认的答案 下面有几个链接 如何将图像转换为位图代码以便在 iPhone 中进行蓝牙打印 https stackoverflow com questions 1383828
  • 在 Swift 中检查一个数组是否包含另一个数组的所有元素

    我想为数组编写一个扩展来检查一个数组是否包含另一个数组的所有元素 在我的用例中它是字符串对象 但我一直得到 Cannot convert value of type T Generator Element to expected argum
  • 在模拟器中运行应用程序时删除本地通知的 iOS 权限警报

    我正在尝试编写验收测试KIF https github com kif framework KIF在一个很早就要求本地通知权限的应用程序上 不幸的是 由于 iOS 模拟器安全原因无法使用 KIF 自动接受 iOS 权限警报 https gi
  • 从 NSError 返回 NSString

    我正在使用NSURLRequest我的 iPhone 应用程序中的类 调用它的方法返回一个NSString这对于连接正常时非常有用 但问题是我需要将 NSError 转换为 NSString 以便我可以将其返回或运行一些if 对此的声明 有
  • 如果 NSExtensionActivationRule 设置为仅音频,则共享扩展不会出现在有功能的应用程序中

    我正在尝试创建一个共享扩展 用户可以从任何有能力的应用程序上传她的录音 该文档甚至有一个简单的示例 请参阅声明共享或操作扩展支持的数据类型 https developer apple com library content document
  • 维护 UISegmentedControl 中的选择

    我可以保持 UISegmentViewControl 段的选定状态吗 即 即使用户选择了另一个段 也可以保持一个段显示为选中状态 我似乎在任何地方都找不到任何可以做到这一点的东西 这是不可能开箱即用的 看如何才能选择 UISegmented
  • 如何在 Xcode 4 中通过一个操作归档多个目标

    我有一个包含多个目标的项目 这些目标都适用于不同的 iOS 应用程序 例如 一个用于精简版的目标 另一个用于专业版的目标 我想立即构建并归档我的所有应用程序 目前 我对每个目标都有一个方案 我用它来独立归档每个应用程序 但现在我必须开始归档
  • iPhone SDK - 在后台线程中运行重复进程

    我有一个iPhone我想在其中每隔一段时间在后台执行一个方法的应用程序1第二 所以在我的主线程中 我有以下代码UIViewController viewDidLoad NSTimer timerWithTimeInterval 1 0 ta
  • 如何在 EKRecurrenceRule 中设置一周中某一天的数组?

    我想在用户选择的特定日期每周添加事件 可以是一个或多个 也可以是一整天 我将用户选择的日期值存储在模型类变量中 但是 当我添加事件并选择日期时 假设今天是星期一 我选择星期二和星期三并保存 然后我查看周一和周三添加的 iPhone 日历 我
  • NSMenuItem、自定义视图和 mouseUp 的奇怪问题:

    我在这里遇到了一个非常非常奇怪的 NSMenu 问题 我使用的大约一半的 NSMenuItems 通过 NSMenuItem 上的 setView 方法具有自定义视图 在此自定义视图中 我实现了 mouseUp 来捕获用户单击菜单项的时间
  • Swift 中 UIImages 的淡入淡出动画

    我有一组图像 我希望它们在登录屏幕的背景中淡出 我无法在 swift 中找到任何可以做到这一点的东西 有什么办法我可以做到吗 这是我当前的代码 override func viewDidLoad super viewDidLoad star
  • 阻止 OSX 变音符号为所有用户禁用 Java 中的 KeyBindings?

    注 我知道这个问题 https stackoverflow com questions 40335285 java keybinds stop working after holding down a key用户必须输入终端命令才能解决此问
  • 如何在内存中存储分子?

    我想将分子存储在内存中 这些可以是简单的分子 Methane CH4 C H bond length 108 7 pm H H angle 109 degrees But also more complex molecules like p

随机推荐