LoginSignup
39
39

More than 5 years have passed since last update.

Re: PinterestのiOSアプリUIアニメーションを再現するまでの道のりを赤裸々に話します

Last updated at Posted at 2014-05-21

PinterestのiOSアプリUIアニメーションを再現するまでの道のりを赤裸々に話します | nanapi TechBlog より

最後に唯一わからなかったことがあるので記載させてください。Pinterestのブログに掲載されていたソースコードなんですが…

return [[CBLPinViewTransition alloc] init];

の部分だけでどうやってあのアニメーションを表現しているのかがわかりませんでした。CBLPinViewTransitionの中身が想定できる人がいたらぜひ教えて欲しいです。

Pinterestの中の人ではないので、あくまでも想像ですが……。

CBLPinViewTransitionというクラスはUIViewControllerAnimatedTransitioningというプロトコルを実装しているはずです。

UIViewControllerAnimatedTransitioningでは

  • - (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext
  • - animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext

というメソッドを実装する必要があります(→ 参考)。

前者は単純にアニメーション実行時間を返します。

後者は実際にアニメーションの実装を行う部分です。アニメーションが開始されるタイミングでこれが呼ばれます。

この時、(id<UIViewControllerContextTransitioning>)transitionContextという形で画面遷移のコンテキストが渡されるのですが、このコンテキストを通して、遷移元のビューコントローラならびに遷移先のビューコントローラのインスタンスにアクセスすることができます。

また、コンテキストにはコンテナビューという遷移アニメーションに利用されるビューがあり、アニメーションに一時的に必要なスナップショットをなどをこれに格納することができます。

基本的な流れとしては……

遷移元のビューコントローラからソースとなるコレクションビューのサイズと位置を取得して、遷移先のビューコントローラのビューのサイズにフィットするようにアニメーションするという形になるでしょうか。

かなりざっくりですが、

- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
  UIViewController *source = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
  UIViewController *destination = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];

  UIView *container = [transitionContext containerView];
  UIView *snapshot = [source.view snapshotViewAfterScreenUpdates:NO];
  [container addSubview:snapshot];

  CGRect sourceRect = ... // 遷移元のサイズと位置を取得
  CGRect destRect = ... // 遷移元から遷移先のサイズと位置を割り出す

  [UIView animateWithDuration:[self transitionDuration:transitionContext]
                   animations:^{
                     // アニメーション処理
                   }
                   completion:^(BOOL finished){
                     [transitionContext completeTransition:YES]; // 遷移の終了を通知
                     // container に追加した subview は自動的に remove されるので、明示的なクリーンアップは基本的には必要ないはず
                   }];
}

こんな感じでしょうか。

destRectを計算する際、sourceRectから遷移先のビューコントローラのビューサイズを相対的に割り出すのが少しトリッキーかもしれませんが、そうでもないかな。

ご参考になれば。

39
39
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
39
39