1

我有一个长按手势识别器的视图:

- (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只有在第二次点击时才到达断点。知道这是为什么吗?

4

1 回答 1

0

我想到了。监听长按的视图包含在一个视图中,该视图在其框架更改时重新定位一些子视图(通过覆盖setFrame:,这似乎是一个坏主意,但我想不出另一种方式)。因此,当长按发生时,它触发了layoutSubviews监听视图父级的父级中的 a,它设置了监听视图父级的框架,重新定位了监听视图,这似乎破坏了响应者链或停用菜单. 解决方案是在覆盖的内部添加一个条件setFrame:,仅在框架实际更改时才触发布局,而长按则不会。我确信有一个更好的替代方案来收听框架更改,可以完全避免这个问题——请随时在评论中提出建议。

于 2012-03-14T19:47:44.957 回答