如何拦截MKMapView或UIWebView对象的触摸事件?

97

我不确定自己做错了什么,但我尝试在一个 MKMapView 对象上捕捉触摸事件。我通过创建以下类来对其进行子类化:

#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>

@interface MapViewWithTouches : MKMapView {

}

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *) event;   

@end

实现代码为:

#import "MapViewWithTouches.h"
@implementation MapViewWithTouches

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

    NSLog(@"hello");
    //[super touchesBegan:touches   withEvent:event];

}
@end

但是当我使用这个类时,控制台上似乎什么也没有显示:

MapViewWithTouches *mapView = [[MapViewWithTouches alloc] initWithFrame:self.view.frame];
[self.view insertSubview:mapView atIndex:0];
任何想法我做错了什么?
15个回答

0
这是我编写的内容,可以在模拟器中允许捏合缩放(我还没有在真正的iPhone上尝试过),但我认为这将是可以的:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    NSLog(@"Touch Began %d", [touches count]);
 reportTrackingPoints = NO;
 startTrackingPoints = YES;
    [viewTouched touchesBegan:touches withEvent:event];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
 if ([[event allTouches] count] == 2) {
  reportTrackingPoints = YES;
  if (startTrackingPoints == YES) {
   BOOL setA = NO;
   NSEnumerator *enumerator = [[event allTouches] objectEnumerator];
   id value;
   while ((value = [enumerator nextObject])) {
    if (! setA) {
     startPointA = [value locationInView:mapView];
     setA = YES;
    } else {
     startPointB = [value locationInView:mapView];
    }
   }
   startTrackingPoints = NO;
  } else {
   BOOL setA = NO;
   NSEnumerator *enumerator = [[event allTouches] objectEnumerator];
   id value;
   while ((value = [enumerator nextObject])) {
    if (! setA) {
     endPointA = [value locationInView:mapView];
     setA = YES;
    } else {
     endPointB = [value locationInView:mapView];
    }
   }
  }
 }
 //NSLog(@"Touch Moved %d", [[event allTouches] count]);
    [viewTouched touchesMoved:touches withEvent:event];
}

- (void) updateMapFromTrackingPoints {
 float startLenA = (startPointA.x - startPointB.x);
 float startLenB = (startPointA.y - startPointB.y);
 float len1 = sqrt((startLenA * startLenA) + (startLenB * startLenB));
 float endLenA = (endPointA.x - endPointB.x);
 float endLenB = (endPointA.y - endPointB.y);
 float len2 = sqrt((endLenA * endLenA) + (endLenB * endLenB));
 MKCoordinateRegion region = mapView.region;
 region.span.latitudeDelta = region.span.latitudeDelta * len1/len2;
 region.span.longitudeDelta = region.span.longitudeDelta * len1/len2;
 [mapView setRegion:region animated:YES];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
 if (reportTrackingPoints) {
  [self updateMapFromTrackingPoints];
  reportTrackingPoints = NO;
 }


    [viewTouched touchesEnded:touches withEvent:event];
}

主要思路是,如果用户使用两个手指,则跟踪值。我在startPoints A和B中记录起始和结束点。然后我记录当前跟踪点,并在完成后,在touchesEnded上调用例程来计算我开始的点之间的线和我结束的点之间的线之间的相对长度,使用简单的斜边计算。它们之间的比率是缩放量:我将区域跨度乘以该量。

希望对某人有用。


0

感谢提供披萨和喊叫声 - 你为我省了很多时间。

multipletouchenabled有时会工作不稳定。

viewTouch.multipleTouchEnabled = TRUE;

最后,当我需要捕捉触摸时(与需要pinchzooms不同时),我切换了视图:
    [mapView removeFromSuperview];
    [viewTouch addSubview:mapView];
    [self.view insertSubview:viewTouch atIndex:0];

但它不能与实时缩放一起使用。它似乎总是缩小。 - Rog

0

我从MystikSpiral的回答中得到了一个“覆盖”透明视图的想法,它完美地解决了我想要实现的问题;快速、简洁的解决方案。

简而言之,我有一个自定义的UITableViewCell(在IB中设计),左侧有一个MKMapView,右侧有一些UILabels。我希望使自定义单元格能够在任何地方触摸并推送一个新的视图控制器。然而,触摸地图直到我在其上方(在IB中)添加了一个与地图视图相同大小的UIView,并将其背景设置为代码中的“clear color”(不认为您可以在IB中设置clearColor?)才能将触摸传递给UITableViewCell:

dummyView.backgroundColor = [UIColor clearColor];

我认为这可能对其他人有所帮助;特别是如果你想为表格视图单元格实现相同的行为。


然而,直接触摸地图时并不会将触摸事件传递到UITableViewCell,直到我在其上方添加了一个与地图视图大小相同的UIView。这是不正确的。地图正在处理触摸事件,因为它具有自己的用户交互,例如滚动等。如果您想检测单元格上的触摸事件而不是与地图交互,请将map.isUserInteractionEnabled = false。然后,您可以在表视图委托中使用didSelectRowAtIndexPath。 - Seamus

0
将MKMapView作为自定义视图的子视图,并实现。
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event

在自定义视图中,应该返回 self 而不是子视图。

你好 Peter,谢谢你的回答!但是我认为这样做的话,MKMapView可能无法获取任何触摸事件,不是吗?我正在寻找一种方法来捕获事件,然后将其转发到MKMapView。 - Martin

0

我不理解为什么其他答案这么复杂。答案其实只有一行代码:

mapView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(mapTapped)))

@objc func mapTapped() {}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接