2012-03-14 17 views
0

、最初の選択に応答していない:UIMenuControllerが、私はそれで長押しジェスチャー認識との見解を持っている唯一の二

- (id)initWithFrame:(CGRect)frame { 
    self = [super initWithFrame:frame]; 
    if (self) {    
     UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressDetected:)]; 
     [self addGestureRecognizer:longPress]; 
     [longPress release]; 
    } 
    return self; 
} 

長押しが検出されると、私はビューの上UIMenuViewControllerを表示したいです単一それで行動し、そのメニュー項目をタップしたとき、私はブロックを実行します:

- (void)longPressDetected:(UILongPressGestureRecognizer *)recognizer { 
    if (recognizer.state == UIGestureRecognizerStateBegan) { 
     [self becomeFirstResponder]; 
     UIMenuController *menuController = [UIMenuController sharedMenuController]; 
     UIMenuItem *actionItem = [[UIMenuItem alloc] initWithTitle:@"Action" action:@selector(someActionSelector)]; 
     [menuController setMenuItems:[NSArray arrayWithObject:actionItem]]; 
     [actionItem release]; 

     [menuController setTargetRect:self.frame inView:self.superview]; 
     [menuController setMenuVisible:YES animated:YES]; 
    } 
} 

- (BOOL)canBecomeFirstResponder { 
    return YES; 
} 

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender { 
    if (action == @selector(copy:) || action == @selector(cut:) || action == @selector(delete:) || 
     action == @selector(paste:) || action == @selector(select:) || action == @selector(selectAll:)) { 
     return NO; 
    } 
    else if (action == @selector(someActionSelector)) { 
     return YES; 
    } 
    else { 
     return [super canPerformAction:action withSender:sender]; 
    } 
} 

- (void)someActionSelector { 
    if (self.actionBlock) { 
     self.actionBlock(); 
    } 
} 

問題は、第二長押しタップコンボ後にこの唯一の作品です。私が最初にビューを長押しするとメニューが表示されますが、メニューをタップすると何も起こりません。もう一度メニューが表示されたら、タップしてブロックを実行します。

デバッガは、someActionSelectorのブレークポイントが2番目のタップでのみ到達することを示しています。これがなぜなのか?

+0

'UIGestureRecognizerStateBegan'を' UIGestureRecognizerStateRecognized'に変更しようとしましたか? – Costique

答えて

0

私はそれを理解しました。長いプレスを聞いているビューは、そのフレームが変更されたときにいくつかのサブビューを再配置するビュー内に含まれています(setFrame:を上書きすることによって悪い考えですが、別の方法は考えられませんでした)。だから、長押しが起こったときにリスニングビューの親の親にlayoutSubviewsがトリガーされ、リスニングビューの位置を変更したリスニングビューの親のフレームが設定されました。メニュー。解決策は、オーバーライドされたsetFrame:の内部に条件を追加して、フレームが実際に変更された場合にのみレイアウトをトリガすることでした。私は、この問題を完全に回避するフレームの変化を聞くためのよりよい選択肢があると確信しています。

関連する問題