How to Intercept Touches Events on a Mkmapview or Uiwebview Objects

How to intercept touches events on a MKMapView or UIWebView objects?

The best way I have found to achieve this is with a Gesture Recognizer. Other ways turn out to involve a lot of hackish programming that imperfectly duplicates Apple's code, especially in the case of multitouch.

Here's what I do: Implement a gesture recognizer that cannot be prevented and that cannot prevent other gesture recognizers. Add it to the map view, and then use the gestureRecognizer's touchesBegan, touchesMoved, etc. to your fancy.

How to detect any tap inside an MKMapView (sans tricks)

WildcardGestureRecognizer * tapInterceptor = [[WildcardGestureRecognizer alloc] init];
tapInterceptor.touchesBeganCallback = ^(NSSet * touches, UIEvent * event) {
self.lockedOnUserLocation = NO;
};
[mapView addGestureRecognizer:tapInterceptor];

WildcardGestureRecognizer.h

//
// WildcardGestureRecognizer.h
// Copyright 2010 Floatopian LLC. All rights reserved.
//

#import <Foundation/Foundation.h>

typedef void (^TouchesEventBlock)(NSSet * touches, UIEvent * event);

@interface WildcardGestureRecognizer : UIGestureRecognizer {
TouchesEventBlock touchesBeganCallback;
}
@property(copy) TouchesEventBlock touchesBeganCallback;


@end

WildcardGestureRecognizer.m

//
// WildcardGestureRecognizer.m
// Created by Raymond Daly on 10/31/10.
// Copyright 2010 Floatopian LLC. All rights reserved.
//

#import "WildcardGestureRecognizer.h"


@implementation WildcardGestureRecognizer
@synthesize touchesBeganCallback;

-(id) init{
if (self = [super init])
{
self.cancelsTouchesInView = NO;
}
return self;
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
if (touchesBeganCallback)
touchesBeganCallback(touches, event);
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
}

- (void)reset
{
}

- (void)ignoreTouch:(UITouch *)touch forEvent:(UIEvent *)event
{
}

- (BOOL)canBePreventedByGestureRecognizer:(UIGestureRecognizer *)preventingGestureRecognizer
{
return NO;
}

- (BOOL)canPreventGestureRecognizer:(UIGestureRecognizer *)preventedGestureRecognizer
{
return NO;
}

@end

SWIFT 3

let tapInterceptor = WildCardGestureRecognizer(target: nil, action: nil)
tapInterceptor.touchesBeganCallback = {
_, _ in
self.lockedOnUserLocation = false
}
mapView.addGestureRecognizer(tapInterceptor)

WildCardGestureRecognizer.swift

import UIKit.UIGestureRecognizerSubclass

class WildCardGestureRecognizer: UIGestureRecognizer {

var touchesBeganCallback: ((Set<UITouch>, UIEvent) -> Void)?

override init(target: Any?, action: Selector?) {
super.init(target: target, action: action)
self.cancelsTouchesInView = false
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
super.touchesBegan(touches, with: event)
touchesBeganCallback?(touches, event)
}

override func canPrevent(_ preventedGestureRecognizer: UIGestureRecognizer) -> Bool {
return false
}

override func canBePrevented(by preventingGestureRecognizer: UIGestureRecognizer) -> Bool {
return false
}
}

MKMapView Touch events

I think the preferred way of doing this is by creating your own map delegate that responds to the map view events. This way, you can monitor changes to the map view by the user interacting with it as well as code programmatically changing the region

public override void ViewDidLoad()
{
var customDelegate = new CustomMapViewDelegate();
customDelegate.OnRegionChanged += TheMapView_OnRegionChanged;

TheMapView.Delegate = customDelegate;
}

public void TheMapView_OnRegionChanged(object sender, MKMapViewChangeEventArgs e)
{
var latitude = TheMapView.Region.Center.Latitude;
var longitude = TheMapView.Region.Center.Longitude;

// Map change logic goes here
}

public class CustomMapViewDelegate : MKMapViewDelegate
{
public event EventHandler<MKMapViewChangeEventArgs> OnRegionChanged;

public override void RegionChanged(MKMapView mapView, bool animated)
{
if (OnRegionChanged != null)
{
OnRegionChanged(mapView, new MKMapViewChangeEventArgs(animated));
}
}
}

Touch events on MKMapView's overlays

Just in case it might help some of you...
I couldn't find a way to do that but I added an annotation on my overlays (Anyway, i needed to do that to display some information) and then I could get the touch event on this annotation. I know it is not the best way to do it but in my situation, and maybe yours, it works ;) !

Detect touches on webview

look at this question it might help you

How to intercept touches events on a MKMapView or UIWebView objects?



Related Topics



Leave a reply



Submit