インタラクティブな遷移を実装する

本記事では、UIPercentDrivenInteractiveTransitionを用いてインタラクティブな遷移を実装する方法を解説します。

トランジションのカスタマイズ方法

1. 遷移先のVIewControllerのサイズをカスタマイズする / 遷移時のアニメーションを簡易的にカスタマイズする→ こちら
2. 遷移時のアニメーションをカスタマイズする → こちら
3. 遷移をインタラクティブにする → 本記事

インタラクティブ・トランジション

インタラクティブな遷移とは、ユーザの操作に合わせて遷移のアニメーションが追従するものです。例えば、純正の写真アプリで見られるズームイン・ズームアウトによる遷移もインタラクティブなものです。

Image for post
Image for post

また、ナビゲーションバーに実装されているスワイプバックもインタラクティブな遷移の一つです。このような遷移を実装することで、より直感的な操作を可能にします。

UIPercentDrivenInteractiveTransition

インタラクティブな遷移は、UIPercentDrivenInteractiveTransitionで簡単に実装することができます。これは、前回の記事で実装したアニメータによるアニメーションの進行度合いを、パーセンテージで管理するオブジェクトです。update(_:), cancel(), finish()を呼ぶことで、現在の進捗をアニメーションに反映させます。

Image for post
Image for post

本記事では、サイドバーを右側からのスワイプで開くようにする実装を解説します。通常present時(ボタン押下時)のアニメーションの実装は前回の記事を参照してください。

1. ジェスチャを登録する

まず、画面遷移のトリガとなるジェスチャを登録します。今回は、画面右端からのスワイプを利用します。

2. ジェスチャから進行度合いを計算する

ジェスチャを受け取るメソッドにて、遷移の進行度合いを0~1の間で決定します。

右側からのスワイプは座標がマイナスになるため、abs()メソッドを用いて絶対値で計算しています。

3. UIPercentDrivenInteractiveTransitionを生成し、進行度合いを伝える

ジェスチャのstate.changedの場合、先ほど計算したprogressをUIPercentDrivenInteractiveTransitionのupdate(_:)メソッドに渡します。加えて、適宜cancel()及びfinish()メソッドも呼び出します。今回、進行度合いが50%未満の場合はキャンセル扱いとしました。

4. フラグ及び遷移処理を実装する

インタラクティブ・トランジションが開始されているかどうかを保持するフラグを作成し、ジェスチャのstateに合わせて更新します。また、ジェスチャ開始時に遷移を実行します。

前回記事では遷移先のSideBarViewControllerを拡張してtransitioningDelegateを継承していましたが、今回は遷移元のViewControllerにジェスチャを登録するため、ViewController側に継承させます。

5. transitioningDelegateにて、interactionControllerを指定する

遷移が始まると、遷移先のViewControllerに紐づけられたtransitioningDelegateinteractionControllerForPresentation(using:)メソッド(dismiss時にはinteractionControllerForDismissal(using:))が呼ばれます。ここで、interactionHasStartedフラグがtrueの時に先ほど生成したinteractionControllerを返り値として渡します。こうすることで、カスタムアニメータによる遷移アニメーションの進行度合いをinteractionControllerが管理することになります。

ボタン押下時など、インタラクティブでない通常の遷移を行う時にはinteractionHasStartedフラグはfalseとなり、nilを返却します。nilが渡された場合、カスタムアニメータは通常通りに遷移アニメーションを実行します。

6. completionCurveを指定する

UIPercentDrivenInteractiveTransitionのcompletionCurveはデフォルトで.easeInOutが設定されていると記載がありますが、この値を指定しないと遷移の終了時及びキャンセル時の挙動がおかしくなります。デフォルトの.easeInOutを再度指定しても良いですが、指の動きに合わせるためにここでは.linearを指定します。

以上で、スワイプによるインタラクティブな画面遷移の実装は完了です。UIPercentDrivenInteractiveTransitionをサブクラス化し、ジェスチャの登録やフラグの管理をこの中で行う書き方もできます(参考)。

Image for post
Image for post

サンプルコード

以下は、本記事で解説したコードのまとめです。UIPresentationControllerの実装はこちらを、UIViewControllerAnimatedTransitioningの実装はこちらを参照してください。

Written by

iOS Engineer 🎆 Master’s Student 🌄 Japan ⛩

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store