views:

1094

answers:

1

Hello,

I have a situation here, I have to handle touchesBegan for textfield. This textfield is in scrollview.

I tried this so far:

I made a subclass of UIScrollView

@interface CustomScrollView : UIScrollView
{
}
@end

@implementation CustomScrollView

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

@end

Here, I can get the desired result.

Same thing I implemented with textfields. I made a subclass of UITextField:

@interface CustomTextField : UITextField
{
}
@end

@implementation CustomTextField

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

@end

This works fine if the text field is inside a normal view, but it fails when the text field is inside a regular scrollView or my custom scrollview.

Please enlighten me on this

(I am doing this to attain something like this when user long presses a textfield the text in textfield is assigned from Textfield to a label and user can drag this label to some other place in the view )

+1  A: 

By default, UIScrollView delays sending touch events to its child views until it can determine if the touch is supposed to cause a scroll. You can prove this by tapping and holding on your textfield - touchesBegan will fire after a moment.

To resolve, simply set the delaysContentTouches property of your custom scroll view to NO. This can be done through Interface Builder by unchecking "Delay Content Touches". In code, simply do something similar to the following:

_myCustomScrollView.delaysContentTouches = NO;

The touchesBegan method of your CustomTextField will now fire immediately. Be aware, however, that users will no longer be able to scroll within the CustomScrollView if their initial tap is inside of any subview. With delaysContentTouches set to no, try tapping inside of your text field (or any subview for that matter) and swiping - you will see that no scrolling occurs. When delayContentTouches is set to yes, the user can tap and swipe from anywhere within the bounds of the CustomScrollView and cause it to scroll.

If you want the best of both worlds (users scrolling from anywhere and subviews that can respond to touches), you override the hitTest method in your CustomScrollView and send a message to the subview that has been touched. Here's the implementation in the 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;
}

And here is the CustomTextField implementation:

@interface CustomTextField : UITextField {

}

-(void) handleTap:(CGPoint) point;

@end

@implementation CustomTextField

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

@end

This is a hack in that it's not truly handling touches (touchesBegan, touchesEnded, etc.), but it works.

retailevolved