UITextView触摸事件未触发。

4

我有一个 UITextView,我想检测单击事件。

看起来,我只需重写 touchesEnded:withEvent 并检查 [[touches anyObject] tapCount] == 1 即可。然而,此事件甚至不会触发。

如果我像这样重写4个事件:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    NSLog(@"touchesBegan (tapCount:%d)", touch.tapCount);
    [super touchesBegan:touches withEvent:event];
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
        NSLog(@"touches moved");
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    NSLog(@"touchesEnded (tapCount:%d)", touch.tapCount);
        [super touchesEnded:touches withEvent:event];
}

-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
        NSLog(@"touches cancelled");
}

I get output like this:

> touchesBegan (tapCount:1)
> touchesCancelled 
> touchesBegan (tapCount:1) 
> touches moved 
> touches moved
> touches moved 
> touchesCancelled

看起来我从未收到touchesEnded事件。

有什么想法吗?


如果你删除了对super的调用,会发生什么? - Reed Olsen
我曾经用UITextView子类做过类似的事情来检测单击和双击 -- 它在2.x设备上完美运行,但在3.0上却不行。 - Don McCaughey
@Reed 我预计你的文本视图不会滚动。 - Don McCaughey
我的猜测是新的复制/粘贴功能正在干扰touchesEnded事件。我想知道是否可以将其关闭? - Ben Scheirman
3个回答

1
我像这样子类化了UITextview,即使在IOS 5.0.1上也似乎可以工作。关键是要重写touchesBegan,而不仅仅是touchesEnded(这才是我真正感兴趣的)。
@implementation MyTextView


- (id)initWithFrame:(CGRect)frame {
    return [super initWithFrame:frame];
}

- (void) touchesBegan: (NSSet *) touches withEvent: (UIEvent *) event { 
    // If not dragging, send event to next responder
    if (!self.dragging) 
        [self.nextResponder touchesBegan: touches withEvent:event]; 
    else
        [super touchesBegan: touches withEvent: event];
}

- (void) touchesEnded: (NSSet *) touches withEvent: (UIEvent *) event { 
    // If not dragging, send event to next responder
    if (!self.dragging) 
        [self.nextResponder touchesEnded: touches withEvent:event]; 
    else
        [super touchesEnded: touches withEvent: event];
}

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

- (BOOL)canBecomeFirstResponder {
    return NO;
}

- (void)dealloc {
    [super dealloc];
}

1

你的博客链接已更改:http://benscheirman.com/2009/07/detecting-a-tap-on-a-uitextview - Raptor

0

你可以通过重写canPerformAction:withSender:方法来关闭剪切/复制/粘贴功能,只需对不允许的操作返回NO。

参见UIResponder文档...

希望这样能阻止你的触摸事件被吞噬。


我尝试重写这个方法,但遇到了崩溃问题。我为@selector(select:)和@selector(selectAll:)返回了NO,但它仍然允许选择。 - Ben Scheirman
好的,已经修复了崩溃问题(我忘记将其传递给超级对象),但是似乎没有影响。我仍然可以复制文本。 - Ben Scheirman
文档表示此方法还将在响应链中的更高级别中调用,因此您可能还需要在包含视图中重写它... - David Maymudes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接