Search code examples
iosswiftuiviewcontrolleruicontainerview

Container View Controller - Unbalanced calls to begin/end appearance transitions


I'm trying to develop Container View Controller as it is shown in Apple documentation.

For now I have simple init code in viewDidAppear:

presentedVC = self.storyboard!.instantiateViewControllerWithIdentifier(Storyboard.yesNoControllerID)
self.addChildViewController(presentedVC)
presentedID = Storyboard.yesNoControllerID
presentedVC.view.frame = containerView.bounds
self.containerView.addSubview(presentedVC.view)
presentedVC.didMoveToParentViewController(self)

I have implemented exchange method, like in Apple doc:

private func exchangeVC(withVC viewController: UIViewController){
    presentedVC.willMoveToParentViewController(nil)
    self.addChildViewController(viewController)

    viewController.view.frame = newViewStartFrame
    let endFrame = oldViewEndFrame
    self.containerView.addSubview(viewController.view)

    self.transitionFromViewController(presentedVC, toViewController: viewController, duration: 0.25, options: UIViewAnimationOptions.CurveLinear, animations: {
        viewController.view.frame = self.presentedVC.view.frame
        self.presentedVC.view.frame = endFrame
        }) { (finished) in
            self.presentedVC.view.removeFromSuperview()
            self.presentedVC.removeFromParentViewController()
            viewController.didMoveToParentViewController(self)
            self.presentedVC = viewController
    }

}

Then, I have button that is calling simply:

let controller = self.storyboard!.instantiateViewControllerWithIdentifier(presentedID)
exchangeVC(withVC: controller)

With this code, my controllers are animating on screen on button press. But at the end of animation I'm getting:

Unbalanced calls to begin/end appearance transitions for UIViewController: 0x7aecf730.

Can You tell me what I have done wrong? How to get rid of this error/warning?


Solution

  • I had a similar issue. Generally, that warning appears when you try to present the same view controller without dismissing it first, but the transition method should handle all that for you. I ended up fixing it by using

    UIView.animate(withDuration:animations:completion:)
    

    instead of

    UIViewController.transition(from:to:duration:options:animations:completion:)
    

    as you are above. Of course, I had to manually add and remove the subviews as well. I'm not sure why this change worked, but my best guess is that there's something wrong with the UIViewController transition method that issues that warning. Fortunately the fix is really easy.