Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIView, how to determine when touches entered the view

It appears that all the touch methods of a UIView are only called if the touches began within the bounds of that view. Is there a way to have a view respond to a user who has touched outside the view, but then dragged his fingers into the view?

In case it matters, my specific application is for dragging a MKPinAnnotationView (using built-in 4.0 dragging). I want something to happen if the user drags a pin onto another view (which happens to be an AnnotationView as well, but it could be anything). No method for dragging is called until I let go of the pin; and no method no the UIView that's being dragged to seems to be called unless I started by touching from within the view.

Because the superview is a MKMapView, it is difficult to just use the touchesMoved event of that and check if the user is in the right location or not. Thanks!

like image 705
GendoIkari Avatar asked Nov 16 '10 22:11

GendoIkari


2 Answers

So after playing around with it for a while, I found that the answer given here actually gave me what I needed, even though the question being asked was different.

It turns out you can subclass UIGestureRecognizer; and have it handle all the touches for the view that it has been added to (including an MKMapView). This allows all the normal MKMapView interactions to still behave without any problem; but also alerts me of the touches. In touchesMoved, I just check the location of the touch; and see if it is within the bounds of my other view.

From everything I tried; this seems to be the only way to intercept touchesMoved while the user is dragging an MKAnnotation.

like image 132
GendoIkari Avatar answered Nov 05 '22 10:11

GendoIkari


You sure can:

(HitstateView.h)

#import <UIKit/UIKit.h>


@interface HitstateView : UIView {
    id overrideObject;
}

@property (nonatomic, retain) id overrideObject;

@end

(HitstateView.m)

#import "HitstateView.h"


@implementation HitstateView

@synthesize overrideObject;

- (void)dealloc {
    self.overrideObject = nil;

    [super dealloc];
}

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    UIView *hitView = [super hitTest:point withEvent:event];
    if (hitView == self) {
        return overrideObject;
    }
    return hitView;
}

@end

Make this view the size of your touch area. Set the overideObject to the view you want the touches to go. IIRC it ought to be a subview of the HitstateView.

like image 34
v01d Avatar answered Nov 05 '22 09:11

v01d