简体   繁体   English

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

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

I'm not sure what I am doing wrong but I try to catch touches on a MKMapView object.我不确定我做错了什么,但我尝试捕捉对MKMapView对象的触摸。 I subclassed it by creating the following class :我通过创建以下类对其进行了子类化:

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

@interface MapViewWithTouches : MKMapView {

}

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

@end

And the implementation :和实施:

#import "MapViewWithTouches.h"
@implementation MapViewWithTouches

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

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

}
@end

But it looks like when I use this class, I see nothing on the Console :但看起来当我使用这个类时,我在控制台上看不到任何东西:

MapViewWithTouches *mapView = [[MapViewWithTouches alloc] initWithFrame:self.view.frame];
[self.view insertSubview:mapView atIndex:0];

Any idea what I'm doing wrong?知道我做错了什么吗?

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.事实证明,其他方法涉及大量黑客式编程,这些编程不完美地复制了 Apple 的代码,尤其是在多点触控的情况下。

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.将其添加到地图视图中,然后根据您的喜好使用gestureRecognizer 的touchesBegan、touchesMoved 等。

How to detect any tap inside an MKMapView (sans tricks)如何检测 MKMapView 中的任何点击(无技巧)

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

WildcardGestureRecognizer.h通配符手势识别器.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通配符手势识别器.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斯威夫特 3

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

WildCardGestureRecognizer.swift 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
    }
}

After a day of pizzas, screamings, I finally found the solution!经过一天的比萨饼,尖叫声,我终于找到了解决方案! Very neat!井井有条!

Peter, I used your trick above and tweaked it a little bit to finally have a solution which work perfectly with MKMapView and should work also with UIWebView彼得,我在上面使用了你的技巧并对其进行了一些调整,最终得到了一个与 MKMapView 完美配合并且也应该与 UIWebView 配合使用的解决方案

MKTouchAppDelegate.h MKTouchAppDelegate.h

#import <UIKit/UIKit.h>
@class UIViewTouch;
@class MKMapView;

@interface MKTouchAppDelegate : NSObject <UIApplicationDelegate> {
    UIWindow *window;
    UIViewTouch *viewTouch;
    MKMapView *mapView;
}
@property (nonatomic, retain) UIViewTouch *viewTouch;
@property (nonatomic, retain) MKMapView *mapView;
@property (nonatomic, retain) IBOutlet UIWindow *window;

@end

MKTouchAppDelegate.m MKTouchAppDelegate.m

#import "MKTouchAppDelegate.h"
#import "UIViewTouch.h"
#import <MapKit/MapKit.h>

@implementation MKTouchAppDelegate

@synthesize window;
@synthesize viewTouch;
@synthesize mapView;


- (void)applicationDidFinishLaunching:(UIApplication *)application {

    //We create a view wich will catch Events as they occured and Log them in the Console
    viewTouch = [[UIViewTouch alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];

    //Next we create the MKMapView object, which will be added as a subview of viewTouch
    mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
    [viewTouch addSubview:mapView];

    //And we display everything!
    [window addSubview:viewTouch];
    [window makeKeyAndVisible];


}


- (void)dealloc {
    [window release];
    [super dealloc];
}


@end

UIViewTouch.h UIViewTouch.h

#import <UIKit/UIKit.h>
@class UIView;

@interface UIViewTouch : UIView {
    UIView *viewTouched;
}
@property (nonatomic, retain) UIView * viewTouched;

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;

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

@end

UIViewTouch.m UIViewTouch.m

#import "UIViewTouch.h"
#import <MapKit/MapKit.h>

@implementation UIViewTouch
@synthesize viewTouched;

//The basic idea here is to intercept the view which is sent back as the firstresponder in hitTest.
//We keep it preciously in the property viewTouched and we return our view as the firstresponder.
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    NSLog(@"Hit Test");
    viewTouched = [super hitTest:point withEvent:event];
    return self;
}

//Then, when an event is fired, we log this one and then send it back to the viewTouched we kept, and voilà!!! :)
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    NSLog(@"Touch Began");
    [viewTouched touchesBegan:touches withEvent:event];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    NSLog(@"Touch Moved");
    [viewTouched touchesMoved:touches withEvent:event];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    NSLog(@"Touch Ended");
    [viewTouched touchesEnded:touches withEvent:event];
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
    NSLog(@"Touch Cancelled");
}

@end

I hope that will help some of you!我希望这会帮助你们中的一些人!

Cheers干杯

UITapGestureRecognizer *tgr = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handleGesture:)];   
tgr.numberOfTapsRequired = 2;
tgr.numberOfTouchesRequired = 1;
[mapView addGestureRecognizer:tgr];
[tgr release];


- (void)handleGesture:(UIGestureRecognizer *)gestureRecognizer
{
    if (gestureRecognizer.state != UIGestureRecognizerStateEnded)
        return;

    CGPoint touchPoint = [gestureRecognizer locationInView:mapView];
    CLLocationCoordinate2D touchMapCoordinate = [mapView convertPoint:touchPoint toCoordinateFromView:mapView];

    //.............
}

For a MKMapView the real working solution is with gesture recognization !对于 MKMapView,真正有效的解决方案是使用手势识别!

Me I wanted to stop updating the center of the map on my location when I drag the map or pinch to zoom.我想在拖动地图或捏合缩放时停止更新我所在位置的地图中心。

So, create and add your gesture recognizer to the mapView :因此,创建您的手势识别器并将其添加到 mapView :

- (void)viewDidLoad {

    ...

    // Add gesture recognizer for map hoding
    UILongPressGestureRecognizer *longPressGesture = [[[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPressAndPinchGesture:)] autorelease];
    longPressGesture.delegate = self;
    longPressGesture.minimumPressDuration = 0;  // In order to detect the map touching directly (Default was 0.5)
    [self.mapView addGestureRecognizer:longPressGesture];

    // Add gesture recognizer for map pinching
    UIPinchGestureRecognizer *pinchGesture = [[[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPressAndPinchGesture:)] autorelease];
    pinchGesture.delegate = self;
    [self.mapView addGestureRecognizer:pinchGesture];

    // Add gesture recognizer for map dragging
    UIPanGestureRecognizer *panGesture = [[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanGesture:)] autorelease];
    panGesture.delegate = self;
    panGesture.maximumNumberOfTouches = 1;  // In order to discard dragging when pinching
    [self.mapView addGestureRecognizer:panGesture];
}

Look the UIGestureRecognizer Class Reference to see all available gesture recognizer.查看UIGestureRecognizer 类参考以查看所有可用的手势识别器。

Because we've defined the delegate to self, we have to implement the protocole UIGestureRecognizerDelegate :因为我们已经定义了 self 的委托,所以我们必须实现协议 UIGestureRecognizerDelegate :

typedef enum {
    MapModeStateFree,                    // Map is free
    MapModeStateGeolocalised,            // Map centred on our location
    MapModeStateGeolocalisedWithHeading  // Map centred on our location and oriented with the compass
} MapModeState;

@interface MapViewController : UIViewController <CLLocationManagerDelegate, UIGestureRecognizerDelegate> {
    MapModeState mapMode;
}

@property (nonatomic, retain) IBOutlet MKMapView *mapView;
...

And override the methode gestureRecognizer:gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer: in order to allow recognize multiple gestures simultaneously, if I understood right :并覆盖方法gestureRecognizer:gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer: 为了允许同时识别多个手势,如果我理解正确:

// Allow to recognize multiple gestures simultaneously (Implementation of the protocole UIGestureRecognizerDelegate)
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    return YES;
}

Now write the methodes which will be called by our gesture recognizers :现在编写将由我们的手势识别器调用的方法:

// On map holding or pinching pause localise and heading
- (void)handleLongPressAndPinchGesture:(UIGestureRecognizer *)sender {
    // Stop to localise and/or heading
    if (sender.state == UIGestureRecognizerStateBegan && mapMode != MapModeStateFree) {
        [locationManager stopUpdatingLocation];
        if (mapMode == MapModeStateGeolocalisedWithHeading) [locationManager stopUpdatingHeading];
    }
    // Restart to localise and/or heading
    if (sender.state == UIGestureRecognizerStateEnded && mapMode != MapModeStateFree) {
        [locationManager startUpdatingLocation];
        if (mapMode == MapModeStateGeolocalisedWithHeading) [locationManager startUpdatingHeading];
    }
}

// On dragging gesture put map in free mode
- (void)handlePanGesture:(UIGestureRecognizer *)sender {
    if (sender.state == UIGestureRecognizerStateBegan && mapMode != MapModeStateFree) [self setMapInFreeModePushedBy:sender];
}

Just in case somebody is trying to do the same like me: I wanted to create an annotation at the point where the user taps.以防万一有人像我一样试图做同样的事情:我想在用户点击的地方创建一个注释。 For that I used the UITapGestureRecognizer solution:为此,我使用了UITapGestureRecognizer解决方案:

UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTapOnMap:)];
[self.mapView addGestureRecognizer:tapGestureRecognizer];
[tapGestureRecognizer setDelegate:self];

- (void)didTapOnMap:(UITapGestureRecognizer *)gestureRecognizer
{
    CGPoint point = [gestureRecognizer locationInView:self.mapView];
    CLLocationCoordinate2D coordinate = [self.mapView convertPoint:point toCoordinateFromView:self.mapView];
    .......
}

However, didTapOnMap: was also called when I tapped on the annotation and a new one would be created.但是,当我点击注释时也会调用didTapOnMap:并且会创建一个新注释。 The solution is to implement the UIGestureRecognizerDelegate :解决方案是实现UIGestureRecognizerDelegate

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
    if ([touch.view isKindOfClass:[MKAnnotationView class]])
    {
        return NO;
    }
    return YES;
}

You probably will need to overlay a transparent view to catch the touches just like is done so often with UIWebView-based controls.您可能需要覆盖一个透明视图来捕捉触摸,就像使用基于 UIWebView 的控件经常做的那样。 The Map View already does a bunch of special things with a touch in order to allow the map to be moved, centered, zoomed, etc... that the messages are not getting bubbled up to your app. Map View 已经通过触摸做了一些特殊的事情,以便允许移动、居中、缩放地图等......消息不会冒泡到您的应用程序中。

Two other (UNTESTED) options I can think of:我能想到的另外两个(未经测试)选项:

1) Resign the first responder via IB and set it to "File's Owner" to allow file's Owner to respond to the touches. 1)通过IB退出第一响应者并将其设置为“文件的所有者”以允许文件的所有者响应触摸。 I an dubious that this will work because MKMapView extends NSObject, not UIView ans a result the touch events still may not get propagated up to you.我怀疑这会起作用,因为 MKMapView 扩展了 NSObject,而不是 UIView,因此触摸事件仍然可能不会传播给您。

2) If you want to trap when the Map state changes (such as on a zoom) just implement the MKMapViewDelegate protocol to listen for particular events. 2) 如果您想在 Map 状态更改时(例如缩放时)进行捕获,只需实现 MKMapViewDelegate 协议来侦听特定事件。 My hunch is this is your best shot at trapping some interaction easily (short of implementing the transparent View over the Map).我的预感是,这是您轻松捕获某些交互的最佳方法(没有在地图上实现透明视图)。 Do not forget to set the View Controller housing the MKMapView as the map's delegate ( map.delegate = self ).不要忘记将包含 MKMapView 的视图控制器设置为地图的委托( map.delegate = self )。

Good Luck.祝你好运。

I haven't experimented, but there's a good chance MapKit is based around a class cluster, and therefore subclassing it is difficult and ineffective.我还没有尝试过,但很有可能 MapKit 是基于类集群的,因此对其进行子类化既困难又无效。

I'd suggest making the MapKit view a subview of a custom view, which should allow you to intercept touch events before they reach it.我建议将 MapKit 视图设为自定义视图的子视图,这样您就可以在触摸事件到达之前拦截它们。

So after half a day of messing around with this I found the following:所以在搞了半天之后,我发现了以下内容:

  1. As everyone else found, pinching doesn't work.正如其他人发现的那样,捏合是行不通的。 I tried both subclassing MKMapView and the method described above (intercepting it).我尝试了子类化 MKMapView 和上面描述的方法(拦截它)。 And the result is the same.结果是一样的。
  2. In the Stanford iPhone videos, a guy from Apple says that many of the UIKit things will cause alot of errors if you "transfer" the touch requests (aka the two methods described above), and you probably won't get it to work.在斯坦福 iPhone 的视频中,苹果的一个人说,如果你“传输”触摸请求(也就是上面描述的两种方法),很多 UIKit 的东西会导致很多错误,你可能不会让它工作。

  3. THE SOLUTION : is described here: Intercepting/Hijacking iPhone Touch Events for MKMapView .解决方案:在此处描述: Intercepting/Hijacking iPhone Touch Events for MKMapView Basically you "catch" the event before any responder gets it, and interpret it there.基本上你在任何响应者得到它之前“捕捉”事件,并在那里解释它。

In Swift 3.0在 Swift 3.0 中

import UIKit
import MapKit

class CoordinatesPickerViewController: UIViewController {

    @IBOutlet var mapView: MKMapView!
    override func viewDidLoad() {
        super.viewDidLoad()

        let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(clickOnMap))
        mapView.addGestureRecognizer(tapGestureRecognizer)
    }

    @objc func clickOnMap(_ sender: UITapGestureRecognizer) {

        if sender.state != UIGestureRecognizerState.ended { return }
        let touchLocation = sender.location(in: mapView)
        let locationCoordinate = mapView.convert(touchLocation, toCoordinateFrom: mapView)
        print("Tapped at lat: \(locationCoordinate.latitude) long: \(locationCoordinate.longitude)")

    }

}

Make the MKMapView a subview of a custom view and implement使 MKMapView 成为自定义视图的子视图并实现

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event

in the custom view to return self instead of the subview.在自定义视图中返回 self 而不是子视图。

Thanks for the pizza and screamings - you saved me lots of time.谢谢你的披萨和尖叫——你为我节省了很多时间。

multipletouchenabled will work sporadically. multipletouchenabled 将偶尔工作。

viewTouch.multipleTouchEnabled = TRUE;

In the end, I switched out the views when I needed to capture the touch (different point in time than needing pinchzooms):最后,当我需要捕捉触摸时,我切换了视图(与需要缩放不同的时间点):

    [mapView removeFromSuperview];
    [viewTouch addSubview:mapView];
    [self.view insertSubview:viewTouch atIndex:0];

I notice that you can track the number and location of touches, and get the location of each in a view:我注意到您可以跟踪触摸的数量和位置,并在视图中获取每个位置:

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    NSLog(@"Touch Moved %d", [[event allTouches] count]);

 NSEnumerator *enumerator = [touches objectEnumerator];
 id value;

 while ((value = [enumerator nextObject])) {
  NSLog(@"touch description %f", [value locationInView:mapView].x);
 }
    [viewTouched touchesMoved:touches withEvent:event];
}

Has anyone else tried using these values to update the map's zoom level?有没有其他人尝试使用这些值来更新地图的缩放级别? It would be a matter of recording the start positions, and then the finish locations, calculating the relative difference and updating the map.这将是记录开始位置,然后是结束位置,计算相对差异并更新地图的问题。

I'm playing with the basic code provided by Martin, and this looks like it will work...我正在使用 Martin 提供的基本代码,这看起来会起作用......

Here's what I put together, that does allow pinch zooms in the simulator (haven't tried on a real iPhone), but I think would be fine:这是我放在一起的内容,它确实允许在模拟器中进行缩放(尚未在真正的 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];
}

The main idea is that if the user is using two fingers, you track the values.主要思想是,如果用户使用两根手指,您可以跟踪这些值。 I record the starting and ending points in startPoints A and B. Then I record the current tracking points, and when I'm done, on touchesEnded, I can call a routine to calculate the relative lengths of the line between the points I start with, and the line between the point I end with using simple hypotenuse calc.我在startPoints A和B中记录起点和终点。然后我记录当前的跟踪点,当我完成后,在touchesEnded上,我可以调用一个例程来计算我开始的点之间的线的相对长度,以及我使用简单斜边计算结束的点之间的线。 The ratio between them is the zoom amount: I multiply the region span by that amount.它们之间的比率是缩放量:我将区域跨度乘以该量。

Hope it's useful to someone.希望它对某人有用。

I took the idea of an "overlay" transparent view, from MystikSpiral's answer, and it worked perfectly for what I was trying to achieve;我从 MystikSpiral 的回答中提出了“叠加”透明视图的想法,它非常适合我想要实现的目标; quick, and clean solution.快速,干净的解决方案。

In short, I had a custom UITableViewCell (designed in IB) with a MKMapView on the left-hand-side and some UILabels on the right.简而言之,我有一个自定义 UITableViewCell(在 IB 中设计),左侧有一个 MKMapView,右侧有一些 UILabels。 I wanted to make the custom cell so you could touch it anywhere and this would push a new view controller.我想制作自定义单元格,以便您可以在任何地方触摸它,这将推动一个新的视图控制器。 However touching the map didn't pass touches 'up' to the UITableViewCell until I simply added a UIView of the same size as the map view right on top of it (in IB) and made it's background the 'clear color' in code (don't think you can set clearColor in IB??):然而,触摸地图并没有将触摸“向上”传递给 UITableViewCell,直到我只是在它的顶部(在 IB 中)添加了一个与地图视图相同大小的 UIView 并使其背景成为代码中的“清晰颜色”(不认为您可以在 IB 中设置 clearColor 吗??):

dummyView.backgroundColor = [UIColor clearColor];

Thought it might help someone else;认为它可能会帮助别人; certainly if you want to achieve the same behaviour for a table view cell.当然,如果您想为表格视图单元格实现相同的行为。

I don't understand why other answers are so complicated.我不明白为什么其他答案如此复杂。 The solution is really just one line:解决方案实际上只是一行:

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

@objc func mapTapped() {}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM