Exception "Application tried to present a fashionable active controller" crash only in iOS 8

UIPopoverController *popCtrl = [[UIPopoverController alloc] initWithContentViewController:self.rootViewController.navigationController]; popCtrl.delegate = self; [popCtrl presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES]; 

This code is in the action of the button, where the button is the "sender".

The line with presentPopoverFromBarButtonItem throws an exception caused by the reason: Application tried to present modally an active controller DetailViewController: 0x15a54c00 . DetailViewController is the self in this case, and it is only a delegate to popCtrl, so I don’t see how it can try to render modally. It should represent rootViewController.navigationController.

As you might guess from the names, the rootViewController and detailViewController are inside the SplitViewController, but before trying to represent the rootViewController using a popover, it will be removed from the SplitViewController.

This only happens in iOS 8 when building with the iOS 8 SDK. It also does not play 100%. In most cases, this exception occurs, but sometimes after restarting the application, this does not happen at all until I restart the application and it starts to repeat all the time again. (I put it in try / catch, so I know that this can happen more than once per run.)

I'm pretty sure this is another iOS 8 bug in the SDK, but did anyone come up with a workaround?

+5
source share
2 answers

I had the same problems updating some of the applications that were originally developed during iOS 5.0. Removing the controller from the UISplitViewController just before using it in the popover did not help, nor did it help to switch to the new UIPopoverPresentationController.

However, I was able to scroll my (main) controller on the left side. More or less, I discovered that the β€œfunction” was an accident, so I looked where it came from and found it in the Apple iOS SDK 5.1 release notes:

In 5.1, the UISplitViewController class uses the slide style when presenting the left view (previously only in Mail). This style is used when a presentation is initiated either by an existing panel element provided by delegate methods, or by a swipe gesture in the correct presentation. No additional API is required to get this behavior, and all existing APIs, including the instance of the UIPopoverController instance provided by the delegate, will continue to work. If the gesture is not supported in your application, set the presentationWithGesture property of your split view controller to NO to disable the gesture. However, disabling gestures is discouraged since its use provides a consistent user interface in all applications.

(Source: iOS 5.1 Release Notes , requires Apple Developer Login)

I did not test what would happen if you set the specified NO property and if it freed the controller, but I would not have too much hope for it.

Thus, even after manually deleting it from the UISplitViewController, my view controller is still active in this hidden area with the possibility of sliding, which seems to be happening inside the SDK. I know that this still worked fine until iOS 7.x, but I actually believe that now, as a bearable bug, it has closed with iOS 8.0.

As a result, I completely abandoned popover and used the default UISplitViewController behavior for iOS 5.1 and higher. For some additional customization, you can change the UISplitViewController.preferredDisplayMode to suit your needs, it saved me time to update the old code that I had never heard of automatic layout.

+1
source

I use popover in iOS 8 programmatically in IBAction. I do not know if this is a mistake or not, but I know that they made some changes to modal representations and presentations. It has a good WWDC video on it, see if you can find it. The way I do this (keep in mind that this is Swift, so you need to translate the translation a bit):

 let controller = self.settingsVC controller.preferredContentSize = CGSizeMake(345, 234) controller.modalPresentationStyle = UIModalPresentationStyle.Popover var settingsPopController = controller.popoverPresentationController settingsPopController?.delegate = self settingsPopController?.sourceView = self.view settingsPopController?.sourceRect = sender.frame controller.modalPresentationStyle = UIModalPresentationStyle.Popover self.presentViewController(controller, animated: true, completion: nil) 

In this code, self.settingsVC is a property of the ViewController I set, which is initialized by another ViewController in the storyboard, but you can replace the controller with the ViewController, which you need to present as a popover. Also note that your UIViewController class must implement UIPopoverPresentationControllerDelegate. If you need help translating, I would be happy to give you a hand.

0
source

Source: https://habr.com/ru/post/1204293/


All Articles