iOS 17 崩溃,使用已弃用的 keyWindow 自行呈现模态视图控制器

iOS 17 crash with presenting modal view controller on itself using deprecated keyWindow

提问人:Silverness 提问时间:11/14/2023 最后编辑:Silverness 更新时间:11/14/2023 访问量:71

问:

自从从 iOS 15 升级到 iOS 17 以来,当我尝试显示模态弹出框并出现以下错误时,我的 iPad 应用程序一直崩溃,我无法解决问题:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Application tried to present modal view controller on itself. Presenting controller is <VolumeVC: 0x7fc81882c520>.'

对于上下文,我一直在我的应用程序中使用以下实用程序类,以首先获取窗口中最顶部的视图控制器,以便我可以显示一个带有视图控制器的模式弹出窗口。

效用.m

+ (UIViewController*)topViewController {
        
    UIViewController *topVC = [[UIApplication sharedApplication] keyWindow].rootViewController;
    NSLog(@"Utility::topViewController(): topVC is: %@", topVC);
    
    int countLoops = 0;
    while (topVC.presentedViewController != nil) {
        topVC = topVC.presentedViewController;
        NSLog(@"Utility::topViewController(): In loop, topVC is: %@, countLoops is: %i", topVC, countLoops);
        countLoops++;
        if (countLoops > 25) { break; }
    } 
    return topVC;
}

+ (void)showDialogiPad:(UIViewController *)contentVC
       fromPresentingVC:(UIViewController *)presentingVC
                 inView:(UIView *)view
                atFrame:(CGRect)frame
          withDirection:(UIPopoverArrowDirection)direction {
    
    // Choose the presentation style in which the content is displayed in a popover view
    contentVC.modalPresentationStyle = UIModalPresentationPopover;
    
    // Set the popover size, anchor location and direction
    contentVC.popoverPresentationController.sourceRect = frame;
    contentVC.popoverPresentationController.sourceView = view;
    contentVC.popoverPresentationController.permittedArrowDirections = direction;
   
    // Set the arrow direction for the popover
    popoverVC.permittedArrowDirections = direction;
    
    // Present the popover presentation controller
    [presentingVC presentViewController:contentVC animated:YES completion:nil];
}

下面是如何从代码中的其他位置调用此函数的示例:

    // Show the volume view controller in a popover
    [Utility showDialogiPad:volumeVC // volumeVC is a simple view controller I want to show in the popup
        fromPresentingVC:[Utility topViewController]
                  inView:view
                 atFrame:frame
           withDirection:UIPopoverArrowDirectionAny];

几点说明:

  • 此代码将在打开和关闭弹出框时工作 1 到 N 次,但它最终总是会从 iOS 17 开始崩溃。当我连续快速打开和关闭弹出框时,崩溃似乎总是发生。
  • frame并且始终填充正确的值,并且当我在对话框方法中打印它们时,它们始终为非 nil。viewvolumeVCpresentingVCUtility::showDialogiPad
  • 当它崩溃时,调试语句的输出为:+ (UIViewController*)topViewController
Utility::topViewController(): topVC is: <UITabBarController: 0x7fc22d81ae00>
Utility::topViewController(): In loop, topVC is: <VolumeVC: 0x7fc22d01f460>, countLoops is: 0
  • 应用的主窗口是一个 UITabBarController,每个选项卡中都有一个 UISplitViewController。
  • 此应用中没有多个场景,也不使用 UIWindowScene。
  • 我知道从 iOS 13 开始已弃用。当我用以下内容替换代码时:keyWindowtopViewController
+ (UIViewController*)topViewController {
    UIWindowScene *windowScene = (UIWindowScene *)[UIApplication sharedApplication].connectedScenes.allObjects.firstObject;
    UIViewController *topVC = windowScene.windows.firstObject.rootViewController;    
    return topVC;
}

它将工作 1 到 N 次,但最终会因以下错误而崩溃:

*** Terminating app due to uncaught exception 'NSGenericException', reason: 'UIPopoverPresentationController (<UIPopoverPresentationController: 0x7ff05c156890>) should have a non-nil sourceView or barButtonItem set before the presentation occurs.'

感谢您对此的任何帮助。

iOS Objective-C 崩溃 UIPopOverPresentationController KeyWindow

评论


答: 暂无答案