有时候会碰到这样的业务需求,需要截取MKMapView上点击、拖动、缩放、旋转等事件,其实也比较简单,使用
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(nullableUIEvent *)event
这个方法就能捕捉到以上的touch事件。
但是对于基于MKMapView高度自定义的控件,我们需要在确定获取touch事件的同时,同时需要知道获取touch事件的view是什么,也就是- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event 方法返回的UIView控件,才能明确我们接下来需要做什么事情,我需要确定触摸是在MKMapView控件上的空白处,而不是MKMapView.subview,看下面的代码:
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
NSLog(@"touchesBegan touch.view:%@,touch.phase:%ld",touch.view,(long)touch.phase);
[super touchesBegan:touches withEvent:event];
}
触摸MKMapView,获取touch事件,打印出来得到下面的信息
2017-03-09 10:10:20.430 ******[17268:1996514] Method : -[MapNavigationTestViewController touchesBegan:withEvent:]
Line: 370
Content : touchesBegan touch.view:<MKNewAnnotationContainerView: 0x21f7dc90; frame = (0 0; 320 480); autoresize = W+H; autoresizesSubviews = NO; layer = <CALayer: 0x2326ec00>>,touch.phase:0
既然MKNewAnnotationContainnerView这个类名已经知道了,这时runtime.h中的object_getClassName()方法就能很好的解决这个问题了,看下面的代码:
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
NSLog(@"touchesBegan touch.view:%@,touch.phase:%ld",touch.view,(long)touch.phase);
NSString *className1 = @"MKNewAnnotationContainerView";
NSString *className = [NSString stringWithCString:object_getClassName(touch.view) encoding:NSUTF8StringEncoding];
if ([className1 isEqualToString:className])
{
NSLog(@"to do");
}
[super touchesBegan:touches withEvent:event];
}
需要强调的是,这个自定义的MKMapView是在添加了MKAnnotationView的情况下测试的,其他情况读者可以根据上面的方法自行测试验证。