Prettygeek
Prettygeek

Reputation: 2531

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?

Upvotes: 2

Views: 7790

Answers (3)

Chris
Chris

Reputation: 1

I was seeing this unbalanced calls error on iPhones, in button tap handler. traced it to a dismiss(animated: no) followed by a present(.. animated: no)

solution was to do the present in a completion handler for the dismiss call.

Upvotes: 0

Jim Rhoades
Jim Rhoades

Reputation: 3320

This is an easy mistake to make, but Apple's documentation for transition(from:to:duration:options:animations:completion:) states that:

This method adds the second view controller's view to the view hierarchy and then performs the animations defined in your animations block. After the animation completes, it removes the first view controller's view from the view hierarchy.

You were getting that Unbalanced calls to begin/end appearance transitions warning because you were adding the subview once with:

self.containerView.addSubview(viewController.view)

... then adding it again when calling transition(from:to:duration:options:animations:completion:)

Removing the call to addSubview would fix the problem.

Upvotes: 9

nonphoto
nonphoto

Reputation: 192

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.

Upvotes: 2

Related Questions