1

I googled several other questions and tutorials but couldn't find an answer for my question. I want to detect if the user has touched/tapped/hold/clicked the screen. I tried with touchesBegan: withEvent: but it is not firing any events.

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
if ([touch view] == mapView_) {
    NSLog(@"Touches began");
} else NSLog(@"Touches began");

}

Is there another way to detect user interaction throught touching the screen?

rmaddy
  • 314,917
  • 42
  • 532
  • 579
WWJD
  • 1,104
  • 4
  • 12
  • 31
  • It depends what you're trying to achieve. You could use a UIButton or some other sort of control, a gesture recogniser on a view, touchesBegan:... and friends... It all depends, really. – marramgrass Apr 09 '14 at 15:08
  • 1
    `touchesBegan` should work, could you show an example where it doesn't? – Douglas Apr 09 '14 at 15:08
  • @Douglas The question is edited. – WWJD Apr 09 '14 at 15:44
  • @WWJD which class did you add this method to? Is that class actually being used? – Douglas Apr 09 '14 at 16:36
  • @Douglas No. I didn't know I had to add the method to a class. Which class? – WWJD Apr 10 '14 at 07:12
  • 1
    The `touchesBegan:withEvent:` method is defined on the [UIResponder](https://developer.apple.com/library/ios/documentation/uikit/reference/UIResponder_Class/Reference/Reference.html#//apple_ref/occ/instm/UIResponder/touchesBegan:withEvent:) class. When you want to do your own handling of `touchesBegan:withEvent:`, you can create a new class which descends from [UIViewController](https://developer.apple.com/library/ios/documentation/uikit/reference/UIViewController_Class/Reference/Reference.html) (which in turn descends from UIResponder) and then add `touchesBegan:withEvent:` to the new class. – Douglas Apr 10 '14 at 10:06

3 Answers3

1

You have to use UITapGestureRecognizer.

Conform your class to UIGestureRecognizerDelegate protocol.

Instantiate the gesture recognizer. For example, to instantiate a UITapGestureRecognizer, we will do:

UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapFrom:)];

Here, action is the selector which will handle the gesture. Here, our selector handleTapFrom will look something like:

- (void) handleTapFrom: (UITapGestureRecognizer *)recognizer
{
    //Code to handle the gesture
}

The argument to the selector is the gesture recognizer. We can use this gesture recognizer to access its properties, for example, we can find the state of the gesture recognizer, like, UIGestureRecognizerStateBegan, UIGestureRecognizerStateEnded, etc.

Set the desired properties on the instantiated gesture recognizer. For example, for a UITapGestureRecognizer, we can set the properties numberOfTapsRequired, and numberOfTouchesRequired.

Add the gesture recognizer to the view you want to detect gestures for. In our sample code (I will be sharing that code for your reference), we will add gesture recognizers to an imageView with the following line of code:

[self.imageView addGestureRecognizer:tapGestureRecognizer];

After adding the gesture recognizer to the view, set the delegate for the gesture recognizer, i.e. the class which will handle all the gesture recognizer stuff. In our sample code, it would be like:

tapGestureRecognizer.delegate = self;

Note: Assign the delegate after adding the gesture recognizer to the view. Otherwise, the action method won’t be called.

Reference - Here

Community
  • 1
  • 1
DilumN
  • 2,889
  • 6
  • 30
  • 44
  • 1
    You *don't* have to use a gesture recognizer. That's certainly one way to do it, but overriding `-touchesBegan:withEvent:` will work just fine too. – Caleb Apr 09 '14 at 15:23
  • 1
    Also, a tap recognizer won't recognize all touches, so it may not be what the OP wants. – Caleb Apr 09 '14 at 15:29
1

The solution was using UIPanGestureRecogniser.

Here's the code that solved the problems and stopped my headache:

    UIPanGestureRecognizer *tap = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapFrom:)];
[mapView_ setMultipleTouchEnabled:YES];
[mapView_ setUserInteractionEnabled:YES];
mapView_.gestureRecognizers = @[tap];

And then the selector method:

- (void) handleTapFrom: (UIPanGestureRecognizer*)recogniser {
   NSLog(@"Pin");
}
WWJD
  • 1,104
  • 4
  • 12
  • 31
0

You can subclass UIApplication if you are only interested in whether the user touched the screen or not, and implement this method:

- (void)sendEvent:(UIEvent *)event {
    [super sendEvent:event];
    if (event.type == UIEventTypeTouches) {
         // handling code
    }
}

In this case the main.m file would look like this:

int main(int argc, char * argv[])
{
    @autoreleasepool {
        return UIApplicationMain(argc, argv, @"UIApplicationSubclass", @"AppDelegate");
    }
}
David Snabel-Caunt
  • 57,804
  • 13
  • 114
  • 132
Levi
  • 7,313
  • 2
  • 32
  • 44
  • 1
    Might be better to subclass `UIWindow` instead. Subclassing `UIApplication` is rather unusual. The window is still at near the top of the event dispatching process, and should handle all the same events. – Caleb Apr 09 '14 at 15:28