ナビゲーションコントローラーのカスタムトランジションアニメーション
質問
あるビューから別のビューに遷移する際に、カスタムアニメーションを作成するためにいくつかのチュートリアルを見てきました。
カスタムセグエを使用した私のテストプロジェクトは
ここで
はうまく動きますが、ある人が、カスタムセグエの中でカスタムアニメーションを行うことはもう推奨されないと教えてくれたので、カスタムセグエを使用するには
UIViewControllerAnimatedTransitioning
.
このプロトコルを利用したチュートリアルをいくつか追ってみましたが、どれもモーダルプレゼンテーションに関するものでした(たとえば このチュートリアル ).
私がやろうとしているのは、ナビゲーションコントローラツリー内のプッシュセグですが、同じことをショー(プッシュ)セグでやろうとすると、もううまくいきません。
ナビゲーションコントローラのあるビューから別のビューへのカスタム遷移アニメーションを行うための正しい方法を教えてください。
また、すべての遷移アニメーションに1つのメソッドを使用できる方法はありますか?ある日、同じアニメーションを行いたいのに、モーダルとコントローラの遷移のためにコードを2回複製しなければならなくなったら、困ります。
どのように解決するのですか?
ナビゲーション・コントローラでカスタムトランジションを行うには (
UINavigationController
) を使用する必要があります。
-
に適合するようにビューコントローラを定義します。
UINavigationControllerDelegate
プロトコルに準拠するように定義します。たとえば、プライベートクラスの拡張子をビューコントローラの.m
ファイルで、このプロトコルへの準拠を指定することができます。@interface ViewController () <UINavigationControllerDelegate> @end
-
ナビゲーションコントローラのデリゲートとして、実際にビューコントローラを指定することを確認してください。
- (void)viewDidLoad { [super viewDidLoad]; self.navigationController.delegate = self; }
-
実装
animationControllerForOperation
をビューコントローラに実装します。- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController*)fromVC toViewController:(UIViewController*)toVC { if (operation == UINavigationControllerOperationPush) return [[PushAnimator alloc] init]; if (operation == UINavigationControllerOperationPop) return [[PopAnimator alloc] init]; return nil; }
-
プッシュ・ポップ・アニメーションのためのアニメーターを実装する、など。
@interface PushAnimator : NSObject <UIViewControllerAnimatedTransitioning> @end @interface PopAnimator : NSObject <UIViewControllerAnimatedTransitioning> @end @implementation PushAnimator - (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext { return 0.5; } - (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext { UIViewController* toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; [[transitionContext containerView] addSubview:toViewController.view]; toViewController.view.alpha = 0.0; [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{ toViewController.view.alpha = 1.0; } completion:^(BOOL finished) { [transitionContext completeTransition:![transitionContext transitionWasCancelled]]; }]; } @end @implementation PopAnimator - (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext { return 0.5; } - (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext { UIViewController* toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; UIViewController* fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; [[transitionContext containerView] insertSubview:toViewController.view belowSubview:fromViewController.view]; [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{ fromViewController.view.alpha = 0.0; } completion:^(BOOL finished) { [transitionContext completeTransition:![transitionContext transitionWasCancelled]]; }]; } @end
これはフェードトランジションですが、アニメーションは自由にカスタマイズしてください。
-
インタラクティブなジェスチャー(例えば、ネイティブの左から右にスワイプしてポップするようなもの)を処理したい場合、インタラクションコントローラを実装する必要があります。
-
インタラクションコントローラのプロパティ(以下のコードに準拠したオブジェクト)を定義します。
UIViewControllerInteractiveTransitioning
):@property (nonatomic, strong) UIPercentDrivenInteractiveTransition *interactionController;
これは
UIPercentDrivenInteractiveTransition
は、ジェスチャーがどの程度完了したかに基づいてカスタムアニメーションを更新するという重い仕事をこなす、すばらしいオブジェクトです。 -
ビューにジェスチャー認識機能を追加します。ここでは左のジェスチャーレコグナイザーを実装して、ポップをシミュレートしているだけです。
UIScreenEdgePanGestureRecognizer *edge = [[UIScreenEdgePanGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeFromLeftEdge:)]; edge.edges = UIRectEdgeLeft; [view addGestureRecognizer:edge];
-
ジェスチャー認識ハンドラを実装します。
/** Handle swipe from left edge * * This is the "action" selector that is called when a left screen edge gesture recognizer starts. * * This will instantiate a UIPercentDrivenInteractiveTransition when the gesture starts, * update it as the gesture is "changed", and will finish and release it when the gesture * ends. * * @param gesture The screen edge pan gesture recognizer. */ - (void)handleSwipeFromLeftEdge:(UIScreenEdgePanGestureRecognizer *)gesture { CGPoint translate = [gesture translationInView:gesture.view]; CGFloat percent = translate.x / gesture.view.bounds.size.width; if (gesture.state == UIGestureRecognizerStateBegan) { self.interactionController = [[UIPercentDrivenInteractiveTransition alloc] init]; [self popViewControllerAnimated:TRUE]; } else if (gesture.state == UIGestureRecognizerStateChanged) { [self.interactionController updateInteractiveTransition:percent]; } else if (gesture.state == UIGestureRecognizerStateEnded) { CGPoint velocity = [gesture velocityInView:gesture.view]; if (percent > 0.5 || velocity.x > 0) { [self.interactionController finishInteractiveTransition]; } else { [self.interactionController cancelInteractiveTransition]; } self.interactionController = nil; } }
-
ナビゲーション・コントローラーのデリゲートでは、さらに
interactionControllerForAnimationController
デリゲートメソッド- (id<UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController interactionControllerForAnimationController:(id<UIViewControllerAnimatedTransitioning>)animationController { return self.interactionController; }
-
UINavigationController custom transition tutorial"でググるとたくさんヒットしますよ。あるいは WWDC 2013 カスタム トランジション ビデオ .
関連
-
[解決済み] カスタムオブジェクトを含むNSMutableArrayをソートするにはどうすればよいですか?
-
[解決済み] iOS7でスタイルUITableViewStyleGroupedを持つUITableViewの上部に余分なパディングがあるのはなぜですか?
-
[解決済み] Xcode 6のバグ:Interface Builderファイル内の不明なクラス
-
[解決済み] フレームワークを使用したiOSアプリがデバイス上でクラッシュ、dyld: ライブラリがロードされない、Xcode 6 Beta
-
[解決済み] UIViewController のビューが表示されているかどうかを確認する方法
-
[解決済み] IBOutletsはARCのもとで強くなるべきか、弱くなるべきか?
-
[解決済み] UIButtonのタイトルを左揃えにするにはどうしたらよいですか?
-
[解決済み】iPhoneアプリケーションにカスタムフォントを埋め込むことはできますか?
-
[解決済み】Storyboardのログイン画面のベストプラクティス、ログアウト時のデータクリアの処理について
-
[解決済み] ナビゲーションコントローラスタック、サブビュー、モーダルコントローラを使用せずに、ビューコントローラの変化をアニメーション化する?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Xcode 6.3 - 現在の iOS Development 証明書または保留中の証明書要求がすでにあります。
-
[解決済み] Xcode 7のエラーです。"Missing iOS Distribution signing identity for ..." (iOS配布用署名IDがありません)
-
[解決済み] SwiftでStringを配列に分割する?
-
[解決済み] Objective-Cで文字列が空かどうかをテストするにはどうすればよいですか?
-
[解決済み] iOS 13 のフルスクリーンでモーダルを表示する
-
[解決済み] UITableViewCell、スワイプ時に削除ボタンを表示させる
-
[解決済み] iOS Simulatorでネットワークを無効にすることは可能ですか?
-
[解決済み] 「GCC使用時に「Xcode/iOSのライセンスに同意するには管理者権限が必要です。rootでsudoを使用して再実行してください。
-
[解決済み] iphoneアプリのベータテストはどのように行うのですか?
-
[解決済み] コア・データ エンティティの全インスタンスを削除する最短の方法