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
How to Open Phone Settings When a Button Is Clicked
Easiest Way to Detect Internet Connection on Ios
Controlling the Screenshot in the iOS 7 Multitasking Switcher
Ios: Convert Utc Nsdate to Local Timezone
Prevent Screen Capture in an iOS App
How to Detect Avplayer and Get Url of Current Video from Wkwebview
Converting Storyboard from Iphone to Ipad
How to Select Multiple Images from Uiimagepickercontroller
How to Record a Conversation/Phone Call on Ios
-Didselectrowatindexpath: Not Being Called
How to Change Uipickerview Height
Get Location Updates For iOS App Even When Suspended
Core Data: Quickest Way to Delete All Instances of an Entity
How to Change Image Tintcolor in iOS and Watchkit
How to Record Video of Front and Back Camera At a Time in Ios
Force View Controller to Reload to Refresh Uiappearance Changes