在UIScrollView中处理UITextField的touchesBegan方法

时间:2009-12-19 04:53:05

标签: iphone objective-c uitextfield

我有一个情况,我必须为文本字段处理touchesBegan。此文本字段位于scrollview中。

到目前为止我试过这个:

我创建了UIScrollView的子类

@interface CustomScrollView : UIScrollView
{
}
@end

@implementation CustomScrollView

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

@end

在这里,我可以得到理想的结果。

我用textfields实现了同样的东西。我创建了UITextField的子类:

@interface CustomTextField : UITextField
{
}
@end

@implementation CustomTextField

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

@end

如果文本字段位于普通视图中,则此方法可以正常工作,但当文本字段位于常规scrollView或我的自定义scrollview中时,它会失败。

请赐教我这个

(我这样做是为了在用户长按文本字段时获得类似的内容,文本字段中的文本从Textfield分配到标签,用户可以将此标签拖到视图中的其他位置)

2 个答案:

答案 0 :(得分:6)

默认情况下,UIScrollView会将触摸事件发送到其子视图,直到它可以确定触摸是否应该导致滚动。你可以通过点击并按住你的文本字段来证明这一点 - touchesBegan会在片刻之后开火。

要解决此问题,只需将自定义滚动视图的delaysContentTouches属性设置为NO即可。这可以通过取消选中“延迟内容触摸”来通过Interface Builder完成。在代码中,只需执行类似以下操作:

_myCustomScrollView.delaysContentTouches = NO;

CustomTextField的touchesBegan方法现在将立即触发。但请注意,如果用户的初始点击位于任何子视图内,用户将无法再在CustomScrollView中滚动。将delaysContentTouches设置为no,尝试点击文本字段(或任何子视图)内部并轻扫 - 您将看到没有滚动发生。当delayContentTouches设置为yes时,用户可以从CustomScrollView的边界内的任何位置点击并滑动,并使其滚动。

如果您想要两全其美(用户从任何地方滚动和可以响应触摸的子视图),您可以覆盖CustomScrollView中的hitTest方法并向已触摸的子视图发送消息。这是CustomScrollView中的实现:

-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent*)event {
    UIView *hitView = [super hitTest:point withEvent:event];

    if([hitView class] == [CustomTextField class]) {
        [(CustomTextField *) hitView handleTap:point]; 
    } 

    return hitView;
}

这是CustomTextField实现:

@interface CustomTextField : UITextField {

}

-(void) handleTap:(CGPoint) point;

@end

@implementation CustomTextField

-(void) handleTap:(CGPoint) point {
    // Implement your handling code here
}

@end

这是一个黑客,它不是真正处理触摸(touchesBegan,touchesEnded等),但它的工作原理。

答案 1 :(得分:3)

我还实现了一个CustomUIScrollView作为UIScrollView的子类,并覆盖了touchesBegan方法:

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    if (!self.dragging)
    {
        [self.nextResponder touchesBegan:touches withEvent:event];
    }
    else
    {
        [super touchesBegan:touches withEvent:event];
    }
}

在interfacebuilder中,我将scrollview对象的自定义类设置为CustomUIScrollView,在“触摸”部分中,我停用了可取消内容触摸。现在我可以在我的UITextField的ViewController中使用touchesBegan方法,以便在检测到键盘外部的触摸时让键盘消失。

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [[event allTouches] anyObject];
    if ([myTextField isFirstResponder] && [touch view] != myTextField)
    {
        [myTextField resignFirstResponder];
    }
    [super touchesBegan:touches withEvent:event];
}