8

My UISplitViewController basically works like a charm except that there is an annoying error message displayed when transitioning the first time (first time only!) from the master table view to the detail view.

Unbalanced calls to begin/end appearance transitions for <UINavigationController: 0x160015600>.

Both the master and the detail view controller are embedded in a UINavigationController. However, the error only occurs when setting the following (which is necessary for logic behavior on the iPhone):

class MySplitViewController: UISplitViewController, UISplitViewControllerDelegate {
    override func viewDidLoad() {
        super.viewDidLoad()
        self.delegate = self
    }

    func splitViewController(splitViewController: UISplitViewController, collapseSecondaryViewController secondaryViewController: UIViewController, ontoPrimaryViewController primaryViewController: UIViewController) -> Bool {
        return true
    }
}

It would be great if anyone could provide a solution to this issue, thanks in advance.

BTW: the split view controller was set up in the storyboard

Presenting the detail view controller is done in the tableView:didSelectRowAtIndexPath: method like this:

if let detailViewController = delegate as? DetailViewController {
    detailViewController.navigationItem.leftItemsSupplementBackButton = true
    detailViewController.navigationItem.leftBarButtonItem = splitViewController!.displayModeButtonItem()
    splitViewController!.showDetailViewController(detailViewController.navigationController!, sender: self)
}
borchero
  • 5,562
  • 8
  • 46
  • 72
  • Facing the same issue while building everything programatically as well. So I suppose whether it is done on storyboard or programatically, this issue occurs. – user1046037 Feb 27 '16 at 23:48
  • Refer - http://cdn3.raywenderlich.com/wp-content/uploads/2015/05/MathMonsters-Swift-Final.zip and then add the `func splitViewController(splitViewController: UISplitViewController, collapseSecondaryViewController secondaryViewController: UIViewController, ontoPrimaryViewController primaryViewController: UIViewController) -> Bool { return true }` – user1046037 Feb 27 '16 at 23:50
  • Try it on the iPhone – user1046037 Feb 27 '16 at 23:51

2 Answers2

2

Most probably, your first transition from master (UITableView in UIViewController?) to detail (UIViewController) view in your UISplitViewController starts before the active/current view has finished displaying itself.

A possible reason for this is that you are possibly trying to present the first "instance" of the detail view in the viewDidLoad() method of you master UIViewController? In such a case, you app might try to present the detail view prior to master view finished appearing. Note the difference here between view did load a view and view did appear:

override func viewDidLoad()

Description:

Called after the controller's view is loaded into memory.

This method is called after the view controller has loaded its view hierarchy into memory.


override func viewDidAppear(animated: Bool)

Description:

Notifies the view controller that its view was added to a view hierarchy. You can override this method to perform additional tasks associated with presenting the view.

Now, as you question doesn't show how you load your initial detail view, the following advice is maybe already heeded by yourself, but anyway: if your detail view is presented from the viewDidLoad(), try to move this to the viewDidAppear() method:

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(true)

    // present/load detail view here instead
}
dfrib
  • 70,367
  • 12
  • 127
  • 192
  • Sorry for not clarifying when I present the detail view controller, check out the edited question. Still, thanks for your effort, that's what I had read before asking this question as well, however I can't think of a way my application is doing this. – borchero Dec 27 '15 at 19:39
  • @OliverBorchert Hmm, then without a more detailed view of your code, I don't really know. Do you possible animate some transition at some point in the first state change to detail? (`animation: ...`). If so, possibly set such animations to `false` for testing if they are the reason for your error (i.e., causing overlaying transitions) – dfrib Dec 27 '15 at 22:17
  • I really only have the split view controller in my application :/ – borchero Dec 27 '15 at 22:19
  • I suspect `self.delegate = self` is the source of the error. Usually you set some type instance *within* your class as the delegate (i.e. `var textField = UITextField` has a delegate defined as `textField.delegate = self`). Using `self.delegate = self` might create a loop behaviour for callbacks, which e.g. overlay two views instantaneously (in so animating two transitions at once). – dfrib Dec 27 '15 at 22:33
0

This might be too late an answer, but anyways, I solved this using perform segue instead of showDetailViewController

Naveen Ramanathan
  • 2,166
  • 1
  • 19
  • 21
  • `showDetailViewController` has some special purpose in a `UISplitViewController` it pushes / presents depending on the size classes (adaptive). So it is better to use `showDetailViewController`, but this seems to be a problem – user1046037 Nov 23 '17 at 08:31