13

UINavigationControllerベースのアプリケーションでバックボタンに機能を追加したいのですが、バックボタンを長押しするとrootにポップアップします。しかし、ジェスチャ認識装置をどこに取り付けるべきかはわかりません。 UINavigationBarをサブクラス化し、長押しが左ボタン領域にあるかどうか試してみますか?UINavigationItemの戻るボタンの長押しを検出します

これまでにも同様の機能を追加している人について聞いたことがあります。誰にでもアイデアはありますか?

答えて

6

UIGestureRecognizersはUIViewとUIViewのサブクラスにしか追加できないと思います。

http://developer.apple.com/library/ios/#documentation/uikit/reference/UIView_Class/UIView/UIView.html

戻るボタンがNSObjectのから下降UIBarButtonItemです。したがって、あなたはあなたがしかし、UIBarButtonItemにカスタムビューを追加することができます

UILongPressGestureRecognizer *longPressGesture = 
      [[[UILongPressGestureRecognizer alloc] 
       initWithTarget:self action:@selector(longPress:)] autorelease]; 

[self.navigationItem.backBarButtonItem addGestureRecognizer:longPressGesture]; 

を使用して、標準のバックボタンにジェスチャー認識を添付することができません。 backBarButtonItemにプロパティを設定すると、あなたは押すことを次のビューに適用されますので、あなたは、しかし、注意する必要があり

UIView *myTransparentGestureView = [[UIView alloc] initWithFrame:CGRectMake(0,0,40,30)]; 
[myTransparentGestureView addGestureRecognizer:longPressGesture]; 
[self.navigationItem.backBarButtonItem setCustomView:myTransparentGestureView]; 
// Or you could set it like this 
// self.navigationItem.backBarButtonItem.customView = myTransparentGestureView; 
[myTransparentGestureView release]; 

:カスタムビューは、同じように簡単になどのUIView、UIButton、UILabel、

例かもしれません。あなたがビューBをプッシュするビューAを持っていて、ビューBで戻るときにジェスチャーを認識させたい場合は、ビューAに設定する必要があります。

+0

backButtomItemのdidnのカスタムビューにジェスチャー認識を追加します私のために働く...認識者は発射を拒否する。上記のコードで作業できるようにしましたか? – kevboh

+0

backBarButtonItemは読み取り専用なので、カスタム表示を受け付けないため、動作しない可能性があります。この答えのように、独自のleftbarbuttonitemを作成する必要があります。 http://stackoverflow.com/questions/526520/how-to-create-backbarbuttomitem-with-custom-view-for-a-uinavigationcontroller – Andrew

+0

ああ、しかし、私はイメージを見つけるまで私の背中の矢印を失う...おそらくそれだけの価値はありません。とにかく、ありがとう! – kevboh

15

この質問は古いですが、解決策を提示する。ボタン自体(これは理想的でしょう)にジェスチャ認識ツールを追加するのではなく、self.navigationController.navigationBarに追加してから、アクションメソッドでlocationInViewを使用して、戻るボタンを押したかどうかを確認します。私はバックボタンを正確に特定する方法について完全にはわかっていなかったので、x座標が任意の値より小さい最初のサブビューをつかむだけで不器用ですが、有望です。誰かが戻るボタンのフレームを識別する良い方法を持っている場合は、私に教えてください。

- (void)longPress:(UILongPressGestureRecognizer *)sender 
{ 
    if (sender.state == UIGestureRecognizerStateEnded) 
    { 
     // set a default rectangle in case we don't find the back button for some reason 

     CGRect rect = CGRectMake(0, 0, 100, 40); 

     // iterate through the subviews looking for something that looks like it might be the right location to be the back button 

     for (UIView *subview in self.navigationController.navigationBar.subviews) 
     { 
      if (subview.frame.origin.x < 30) 
      { 
       rect = subview.frame; 
       break; 
      } 
     } 

     // ok, let's get the point of the long press 

     CGPoint longPressPoint = [sender locationInView:self.navigationController.navigationBar]; 

     // if the long press point in the rectangle then do whatever 

     if (CGRectContainsPoint(rect, longPressPoint)) 
      [self doWhatever]; 
    } 
} 

- (void)addLongPressGesture 
{ 
    if (NSClassFromString(@"UILongPressGestureRecognizer")) 
    { 
     UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)]; 
     [self.navigationController.navigationBar addGestureRecognizer:longPress]; 
     [longPress release]; 
    } 
} 
+0

クールなアイデア。次回はこれをやる必要があります。あなたのアプローチを試してみます。フォローアップをありがとう! – kevboh

+0

私はポップするためにそこにある長いプレスで大丈夫です - 私には合理的なようです。 –

+0

私はバックボタンにlongPressジェスチャーを設定するのと同じ要件を持っていました。このアプローチの問題は、バックボタンが強調表示された状態にとどまっていないことです。私はcan.ButにcancelsTouchesInViewプロパティを設定してから、longPressHandlerとbackButtonハンドラこれのためのすべてのソリューション? – user1010819

3

私はそれを共有すると思いました。上記の答えは罰金ですが、長押しは、ナビゲーションバーのリーディング1/3であれば、本当に、それは私のために十分に良いことだ:

- (void)longPress:(UILongPressGestureRecognizer *)gr 
{ 
    NSLog(@"longPress:"); 
    UINavigationBar *navBar = [self navigationBar]; 
    CGFloat height = navBar.bounds.size.height; 
    CGPoint pt = [gr locationOfTouch:0 inView:navBar]; 
    //NSLog(@"PT=%@ height=%f", NSStringFromCGPoint(pt), height); 
    if(CGRectContainsPoint(CGRectMake(0,0,100,height), pt)) { 
     [self popToViewController:self.viewControllers[0] animated:YES]; 
    } 
} 
0

は、ここに私のソリューションです:appDelegateで

( applicationDidFinishLaunchingWithOptionsで私のアプリでナビゲーションバーの「所有者」)、:

は、ナビゲーションバーのビューを取得し、全体ビューにジェスチャー認識を追加します。appDelに続いて

// Get the nav bar view 
UINavigationBar *myNavBar = nil; 
for (UIView *view in [self.window.rootViewController.view subviews]) { 
    if ([view isKindOfClass:[UINavigationBar class]]) { 
     NSLog(@"Found Nav Bar!!!"); 
     myNavBar = (UINavigationBar *)view; 
    } 
} 

UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self 
                         action:@selector(backButtonLongPress:)]; 
[myNavBar addGestureRecognizer:longPress]; 
NSLog(@"Gesture Recognizer Added."); 

egate、中 - (無効)backButtonLongPress:(ID)、送信者

チェックジェスチャーは戻るボタンの枠内で発生するかどうかを確認するために:

if ([sender state] == UIGestureRecognizerStateBegan) { 

    // Get the nav bar view 
    UINavigationBar *myNavBar = nil; 
    for (UIView *view in [self.window.rootViewController.view subviews]) { 
     if ([view isKindOfClass:[UINavigationBar class]]) { 
      NSLog(@"Found Nav Bar!!!"); 
      myNavBar = (UINavigationBar *)view; 
     } 
    } 

    // Get the back button view 
    UIView *backButtonView = nil; 
    for (UIView *view in [myNavBar subviews]) { 
     if ([[[view class] description] isEqualToString:@"UINavigationItemButtonView"]) { 
      backButtonView = view; 
      NSLog(@"Found It: %@", backButtonView); 
      NSLog(@"Back Button View Frame: %f, %f; %f, %f", backButtonView.frame.origin.x, backButtonView.frame.origin.y, backButtonView.frame.size.width, backButtonView.frame.size.height); 
     } 
    } 

    CGPoint longPressPoint = [sender locationInView:myNavBar]; 
    NSLog(@"Touch is in back button: %@", CGRectContainsPoint(backButtonView.frame, longPressPoint) ? @"YES" : @"NO"); 
    if (CGRectContainsPoint(backButtonView.frame, longPressPoint)) { 
     // Place your action here 
    } 

    // Do nothing if outside the back button frame 

} 
関連する問題