2013-12-17 3 views
16

コールバックまたはイベントをビューコントローラで取得するときに、interactivePopGestureRecognizerによって解決(ポップ)されるクリーンなソリューションはありますか?interactivePopGestureRecognizerのコールバック/イベントの拒否を取得する

明確にするには、コントローラがこのジェスチャ認識子によってポップされる前に、一番上のコントローラ(および他のコントローラ)で呼び出される明示的なメソッドが必要です。私はナビゲーションコントローラ上のイベントを取得し、適切なコントローラにイベントを送信したいと私は使用したくないviewWillAppearまたはviewWillDissapear ...

私はターゲット/セレクタのペアを追加することですジェスチャーには2つの問題しかありません。コントローラーが解雇されるかどうかは、まずは直接の情報を得ることができません(いずれにしてもUIGestureRecognizerStateEndedが発動します)。コントローラが却下された後、私は認識装置からターゲットを削除する必要があります。

私はいくつかの情報を代理人に送信する必要があるコントローラがいくつかあります。 「完了」ボタンと「キャンセル」ボタンがあると、イベントがトリガーされ、デリゲートメソッドが呼び出され、コントローラがポップされます。できるだけコードを変更する必要はありません。

このジェスチャーのもう1つの状況は、アラートビューを表示してアクションを元に戻す可能性があります。このジェスチャーが終了したときにアラートビューを表示する方法はありますか?コントローラがポップされるか戻されるかを選択します。

+0

興味深い問題です。 'interactivePopGestureRecognizer'を無効にして自分自身を登録するか、iOS 7の[対話的な遷移](http://www.objc.io/issue-5/view-controller-transitions.html) –

+0

を使用する必要があると感じています私はあなたが正しいかもしれないと恐れています。これは一般的な問題ではないと奇妙に思えます。私は、少なくともいくつかの点でこれを実装する必要があるかなりの数のアプリを期待しています。カスタムトランジションを実装する上で最悪のことは、各コントローラでジェスチャを明示的に無効にし、ポップした後(または別のものをプッシュした後)に再度有効にする必要があることです。 –

答えて

38

私はこれが昔であることは知っていますが、同様の問題に直面している可能性がある他の人にとってはわかります。ここで私が使ったアプローチがあります。最初にUINavigationControllerDelegateをナビゲーションコントローラに登録します。デリゲートは実装する必要があります。

のObjective-C

func navigationController(navigationController: UINavigationController, willShowViewController viewController: UIViewController, animated: Bool) 

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated

スウィフトので、実装は次のようになります。

のObjective-C

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated 
{ 
     id<UIViewControllerTransitionCoordinator> tc = navigationController.topViewController.transitionCoordinator; 
     [tc notifyWhenInteractionEndsUsingBlock:^(id<UIViewControllerTransitionCoordinatorContext> context) { 
      NSLog(@"Is cancelled: %i", [context isCancelled]); 
    }]; 
} 

スウィフト

func navigationController(navigationController: UINavigationController, willShowViewController viewController: UIViewController, animated: Bool) { 
    if let coordinator = navigationController.topViewController?.transitionCoordinator() { 
     coordinator.notifyWhenInteractionEndsUsingBlock({ (context) in 
      print("Is cancelled: \(context.isCancelled())") 
     }) 
    } 
} 

ユーザが指及び(OBJEC-C)[context isCancelled];(SWIFT)を持ち上げたときに発動するコールバックcontext.isCancelled()戻りますYES/trueアニメーションが逆転した場合(ビューコントローラがポップされなかった場合)、そうでない場合はNO/false。関連するビューコントローラと、リリース時に完了したアニメーションの割合などのように、使用可能なものはcontextです。

+1

「ナビゲーションコントローラにイベントを取得して、適切なコントローラにイベントを送信したくない」とは言えませんが、それでもかなり良いです。 –

+1

はい、あなたには完璧ではないことは分かっていますが、このタイプの問題をgoogleにしようとすると、あなたの質問が最初の1つです。そして技術的にはナビゲーションコントローラではなくデリゲートでこれを取得していますが、コントローラでメソッドを呼び出す必要があります。それを試してみたい場合は、isCancelledを使用して通知するかどうかを確認し、[context viewControllerForKey:UITransitionContextFromViewControllerKey]を使用してコントローラに通知するようにします。しかし、もう一度あなたは正しいです、それはあなたのために欲しいものではありません。 –

+1

実際最上位コントローラを有することを私はこのようなものを実現することができる: IF([TCのrespondsToSelector:@selector(controllerDismissedByPopGesture :)]){ [performSelector TC:@selector(controllerDismissedByPopGesture :) withObject:@([コンテキストisCancelled ])]; } 私はこのタイプのコードが大変好きではありませんが、まさに私が必要とするものです。私が必要とするのは、 ' - (void)controllerDismissedByPopGesture:(NSNumber *)isCancelled'をANYコントローラに追加するだけです。たぶんあなたの答えに追加する必要があります... –

関連する問題