iOS UIPageViewController How to soleve the error message "Unbalanced calls to begin/end appearance transitions for" .
Introduction
When I tried to transition some pages so rapidly.
The Xcode shows an error message as below.
Unbalanced calls to begin/end appearance transitions for
The code is below.
class MyPageViewController: UIPageViewController { var maxPage = 3 var currentPage = 0 ~~~~ // SomeCode.... ~~~~ } extension MyPageViewController: UIPageViewControllerDataSource { func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? { guard self.currentPage > self.maxPage else { return nil } self.currentPage += 1 let myAfterVC = MyAfterViewController() return myAfterVC } func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? { guard self.currentPage >= 0 else { return nil } self.currentPage -= 1 let myBeforeVC = MyBeforeViewController() return myBeforeVC } }
Why
This error message is showed up when a new transition begin before an old old is not completed.
Solution
To prepend a new transition before an old one is not completed, I added a transitioning flag in MyPageViewController and change the value in UIPageVieController Delegate.
The true code is below.
class MyPageViewController: UIPageViewController { var isTransitioning = false var maxPage = 3 var currentPage = 0 ~~~~ // SomeCode.... ~~~~ } extension MyPageViewController: UIPageViewControllerDataSource { func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? { guard self.currentPage < self.maxPage, self.isTransitioning == false else { return nil } self.currentPage += 1 let myAfterVC = MyAfterViewController() return myAfterVC } func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? { guard self.currentPage >= 0, self.isTransitioning == false else { return nil } self.currentPage -= 1 let myBeforeVC = MyBeforeViewController() return myBeforeVC } } extension MyPageViewController: UIPageViewControllerDelegate { func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) { self.isTransitioning = true } func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) { self.isTransitioning = false } }