Google Now カードが有効になっているときの iOS 用 Google アプリのレイアウトに似た、一連のカードをテーブル ビューに表示するアプリを作成しています。ユーザーがカードをタップすると、新しいビュー コントローラーへのカスタム トランジションが発生するはずです。これは、基本的にカードが大きくなり、ほとんど画面いっぱいになり、詳細が表示されます。カスタム トランジション自体は、カードが上向きにアニメーション化され、カードを保持する新しいビュー コントローラーである最終的なサイズと位置に達するまでサイズが大きくなるように見えるはずです。
カスタムView Controllerトランジションを使用してこれにアプローチしようとしています。カードがタップされると、カスタム ビュー コントローラー トランジションを で開始しUIModalPresentationCustom
、トランジション デリゲートを設定します。トランジション デリゲートは、それ自体がカスタム アニメーターとカスタム UIPresentationController を提供します。ではanimateTransition:
、新しいビュー コントローラーのビューをコンテナー ビューに追加し、最初にフレームをカードのフレームに設定します(そのため、カードがまだそこにあり、変更されていないように見えます)。次に、提示されたビューのフレームのサイズが大きくなり、位置が変化して最終的な位置に移動するアニメーションを実行しようとしました。
ここに、上記で説明したことを行うコードの一部を示します。短く簡潔にしようとしていますが、必要に応じてさらに情報を提供できます。
移行デリゲート
-(void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
// NOWAnimationDelegate is my own custom protocol which defines the method for asking the presenting VC for the tapped card's frame.
UIViewController<NOWAnimationDelegate> *fromVC = (UIViewController<NOWAnimationDelegate> *)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *finalVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];
// Ask the presenting view controller for the frame of the tapped card - this method works.
toView.frame = [fromVC rectForSelectedCard];
[transitionContext.containerView addSubview:toView];
CGRect finalRect = [transitionContext finalFrameForViewController:finalVC];
[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
toView.frame = finalRect;
}completion:^(BOOL finished) {
[transitionContext completeTransition:YES];
}];
}
カスタム UIPresentationController
-(CGSize)sizeForChildContentContainer:(id<UIContentContainer>)container withParentContainerSize:(CGSize)parentSize {
return CGSizeMake(0.875*parentSize.width, 0.875*parentSize.height);
}
-(CGRect)frameOfPresentedViewInContainerView {
CGRect presentedViewFrame = CGRectZero;
CGRect containerBounds = self.containerView.bounds;
presentedViewFrame.size = [self sizeForChildContentContainer:(UIView<UIContentContainer> *)self.presentedView withParentContainerSize:containerBounds.size];
presentedViewFrame.origin.x = (containerBounds.size.width - presentedViewFrame.size.width)/2;
presentedViewFrame.origin.y = (containerBounds.size.height - presentedViewFrame.size.height)/2 + 10;
return presentedViewFrame;
}
私が見つけているのは、新しいビューがアニメーションの開始直後に最終的なサイズに自動的に設定されていることです。その後、アニメーションは上向きにアニメーション化された新しいビューです。UIPresentationController のドキュメントによると、ブレークポイントを使用frameOfPresentedViewInContainerView
して、呼び出し中に呼び出されていることに気付きました[transitionContext.containerView addSubview:toView]
。これは、おそらくこれが起こっている理由を説明しています。「アニメーションの最後に提示されたビューに割り当てるフレーム四角形」を返しますframeOfPresentedViewInContainerView
ただし、どのように進めるか、またはそれが本当に可能かどうかはわかりません。私が見たカスタム ビュー コントローラー遷移のすべての例では、提示されたビュー コントローラーの最終的なサイズはすべて静的で、アニメーション中は変化しませんでした。アニメーション中に提示されたビューのサイズを変更してカスタム ビュー コントローラーの遷移を実行する方法はありますか、または別の方法でこれにアプローチする必要がありますか?