概要
UIPageViewControllerDataSourceのviewControllerBefore
とviewControllerAfter
メソッドで前後のViewControllerを切り替える場合、両メソッドはジェスチャ途中で発生する為、予期せぬプロパティの保持結果となってしまうケースがある。
ダメなケース
下の例ではスクロールジェスチャ途中でキャンセルした場合でもイベントが着火している場合があり、メンバのindexが操作されてしまい、次回完了時にindexの値が飛んでいるケースが発生する。
extension ViewController: UIPageViewControllerDelegate { func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? { self.index -= 1 let vc = MyViewController() vc.index = self.index return vc } func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? { self.index += 1 let vc = MyViewController() vc.index = self.index return vc } }
スクロール完了ジェスチャを捕捉する
UIPageViewControllerDelegateのdidFinishAnimating
メソッドを使用する
extension ViewController: UIPageViewControllerDataSource, UIPageViewControllerDelegate { //ジェスチャ完了した時のみ保持するパラメータを確定させる func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) { if completed { self.index = self. pendingIndex } } func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? { self. pendingIndex = self.index - 1 let vc = MyViewController() vc.index = self. pendingIndex return vc } func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? { self. pendingIndex = self.index + 1 let vc = MyViewController() vc.index = self. pendingIndex return vc } }
参考
リンク
リンク