`DetailViewController` in "Master-Detail Application" missing `will/didMove(toParentViewController:)`
Originator: | regexident | ||
Number: | rdar://33371864 | Date Originated: | July 18 2017 |
Status: | open | Resolved: | no |
Product: | UIKit | Product Version: | 10.x |
Classification: | Bug | Reproducible: | Always |
Area: UIKit Summary: Xcode’s project template for “Master-Detail Application” has a mis-configured storyboard that triggers a bug in either `UINavigationController` or `UISplitViewController`. The bug causes certain callbacks on the detail view controller to not be fired on dismissal/pop-back. This bug affects both iPhone (without split-view) and iPad (with split-view). Steps to Reproduce: 1. Create new Xcode Project. 2. Choose Master-Detail iOS Application 3. Add the following to `DetailViewController`: ``` override func viewDidDisappear(_ animated: Bool) { super.viewDidDisappear(animated) if self.isMovingFromParentViewController || self.isBeingDismissed { print(type(of: self), #function) } } override func willMove(toParentViewController parent: UIViewController?) { super.willMove(toParentViewController: parent) if parent == nil { print(type(of: self), #function) } } override func didMove(toParentViewController parent: UIViewController?) { super.didMove(toParentViewController: parent) if parent == nil { print(type(of: self), #function) } } ``` 4. Launch app 5. Create entry in `MasterViewController` by tapping '+'. 6. Tap on entry to open `DetailViewController`. 7. Tap back-button 8. Check console. 9. Realize that none of the expected logs are printed. Workaround/Fix: 1. Open Main.storyboard. 2. Remove "showDetail"-Segue from `MasterViewController` to `DetailViewController`. 3. Add a `detailNavigationController` property to `MasterViewController`: ``` var detailNavigationController: UINavigationController? = nil ``` 4. Replace: ``` detailViewController = (controllers[controllers.count-1] as! UINavigationController).topViewController as? DetailViewController ``` with: ``` detailNavigationController = controllers[controllers.count-1] as? UINavigationController detailViewController = detailNavigationController!.topViewController as? DetailViewController ``` in `MasterViewController`. 5. Replace: ``` let controller = (segue.destination as! UINavigationController).topViewController as! DetailViewController ``` with: ``` let controller = segue.destination as! DetailViewController ``` in `MasterViewController`. 6. Add this: ``` override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let storyboard = UIStoryboard(name: "Main", bundle: nil) let detailViewController = storyboard.instantiateViewController(withIdentifier: "detailViewController") as! DetailViewController let object = objects[indexPath.row] as! NSDate detailViewController.detailItem = object detailViewController.navigationItem.leftBarButtonItem = splitViewController?.displayModeButtonItem detailViewController.navigationItem.leftItemsSupplementBackButton = true if let split = splitViewController { split.showDetailViewController(detailViewController, sender: nil) } else { navigationController?.pushViewController(detailViewController, animated: true) } } ``` in `MasterViewController`. Expected Results: Console: ``` DetailViewController … willMove(toParentViewController:) DetailViewController … viewDidDisappear DetailViewController … didMove(toParentViewController:) ``` Observed Results: No such output. Version: 10.x
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!
Possibly related to http://www.openradar.me/18002763
Title: "willMoveToParentViewController not called by UINavigationController when setting its view controllers"