-[UIViewController dismissViewControllerAnimated:completion:] should not reach out to presentingViewController
| Originator: | steipete | ||
| Number: | rdar://30284135 | Date Originated: | 31-Jan-2017 01:54 PM |
| Status: | Open | Resolved: | |
| Product: | iOS | Product Version: | 10.3b1 |
| Classification: | Enhancement | Reproducible: | Always |
When calling -[UIViewController dismissViewControllerAnimated:completion:] this method checks if the receiver has a presented view controller. If it has one, it will dismiss this view controller, making the receiver of this method the top most view controller. However, if the receiver does not have a presented view controller, it checks for presentingViewControler and forwards this message to it, if there is one. This leads to some pitfalls that could easily be avoided by designing this API without the forwarding part. One thing that happens quite easily is this: - View controller R presents a view controller A. - View controller A presents another view controller B. - View controller A then calls dismissViewControllerAnimated:completion: - Immediately after that - maybe through some complex architecture - it triggers a second call to dismissViewControllerAnimated:completion: - View controller A will now dismiss view controller B - After that it will dismiss itself, making view controller R the top most view controller as the second call to dismissViewControllerAnimated:completion: checks for a presentedViewController which by now is nil (because the calls to these methods are delayed by UIKit) and thus forward the call to view controller R This can be worked around by always checking `isBeingDismissed` on the receiver and only call dismissViewControllerAnimated:completion: if this returns NO, however this is a lot of boilerplate and can easily be forgotten. I therefore propose the following: - The receiver should not check presentingViewController but instead should do nothing if presentedViewController is nil - As this would be a breaking API change, there should be a new method introduced with has the described behavior and also makes it clear that this method should be called on the view controller that is presenting the other view controller (i.e. on the same view controller that presentViewController:animated:completion: was called on). This method could be named `dismissPresentedViewControllerAnimated:completion:` - With the new method, dismissViewControllerAnimated:completion: should be deprecated The new method name matches the `presentedViewController` property and makes it clear that the view controller being dismissed is the one that represents the current value of this property. See rdar://30263707
Comments
Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!