Reputation: 2531
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
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
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
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