goal c – iOS 17 crash with presenting modal view controller on itself utilizing deprecated keyWindow

Spread the love


For the reason that improve from iOS 15 to iOS 17, my iPad app has been crashing when I attempt to show modal popovers with the next error and I’m unable to resolve the difficulty:

*** Terminating app on account of uncaught exception 'NSInvalidArgumentException', motive: 'Software tried to current modal view controller on itself. Presenting controller is <VolumeVC: 0x7fc81882c520>.'

For context, I have been utilizing the next utility class all through my app to first get the highest most view controller within the window in order that I can then show a modal popover with a view controller in it.

Utility.m

+ (UIViewController*)topViewController {
        
    UIViewController *topVC = [[UIApplication sharedApplication] keyWindow].rootViewController;
    NSLog(@"Utility::topViewController(): topVC is: %@", topVC);
    
    int countLoops = 0;
    whereas (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)body
          withDirection:(UIPopoverArrowDirection)path {
    
    // Select the presentation type through which the content material is displayed in a popover view
    contentVC.modalPresentationStyle = UIModalPresentationPopover;
    
    // Set the popover dimension, anchor location and path
    contentVC.popoverPresentationController.sourceRect = body;
    contentVC.popoverPresentationController.sourceView = view;
    contentVC.popoverPresentationController.permittedArrowDirections = path;
   
    // Set the arrow path for the popover
    popoverVC.permittedArrowDirections = path;
    
    // Current the popover presentation controller
    [presentingVC presentViewController:contentVC animated:YES completion:nil];
}

An instance of how this will get referred to as from elsewhere within the code is the next:

    // Present the amount 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:body
           withDirection:UIPopoverArrowDirectionAny];

A couple of notes:

  • This code will work 1 to N instances of opening & closing the popover however it should all the time finally crash as of iOS 17. The crash all the time appears to occur once I open and shut the popover shortly in succession.
  • body and view are all the time populated with the proper values, and volumeVC and presentingVC are all the time non-nil once I print them out within the Utility::showDialogiPad dialog methodology.
  • When it crashes, the output of the debug statements in + (UIViewController*)topViewController are:
Utility::topViewController(): topVC is: <UITabBarController: 0x7fc22d81ae00>
Utility::topViewController(): In loop, topVC is: <VolumeVC: 0x7fc22d01f460>, countLoops is: 0
  • The principle window of the app is a UITabBarController with a UISplitViewController in every tab.
  • This app doesn’t have a number of scenes in it nor does it use UIWindowScene.
  • I do know keyWindow is deprecated as of iOS 13. Once I substitute the topViewController code with the next:
+ (UIViewController*)topViewController {
    UIWindowScene *windowScene = (UIWindowScene *)[UIApplication sharedApplication].connectedScenes.allObjects.firstObject;
    UIViewController *topVC = windowScene.home windows.firstObject.rootViewController;    
    return topVC;
}

It can work 1 to N instances however finally it should crash with this error:

*** Terminating app on account of uncaught exception 'NSGenericException', motive: 'UIPopoverPresentationController (<UIPopoverPresentationController: 0x7ff05c156890>) ought to have a non-nil sourceView or barButtonItem set earlier than the presentation happens.'

Thanks for any help with this.

Leave a Reply

Your email address will not be published. Required fields are marked *