iOS UIPageViewControllerで"Unbalanced calls to begin/end appearance transitions for" が出たときの対処方法
English version below
はじめに
UIPageViewControllerを早送りしたときに次のようなエラーが出ました。
Unbalanced calls to begin/end appearance transitions for
そのときのコードはこんな感じです。
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 } }
原因
このエラーメッセージは、現在のUIViewControllerの表示が完了する前に、次のUIViewControllerへ遷移しようとしたときに出るようです。
解決方法
遷移中に再度遷移しないようにフラグをもたせました。
UIPageViewControllerDelegateを通して、で遷移の開始と終了を知ることができます。
したがって、コードでは次のようになります。
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 } }