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
andview
are all the time populated with the proper values, andvolumeVC
andpresentingVC
are all the time non-nil once I print them out within theUtility::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 thetopViewController
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.