带有UIGestureRecognizers的MKMapview

时间:2011-07-26 10:50:53

标签: iphone ipad mkmapview uigesturerecognizer touch-event

所以我在我的iPad上有一个UIView作为我的Root视图。我添加了一些子视图,其中还有一个MKMapView。

我想要达到的目的是检测屏幕上的三指滑动,以便我能对它作出反应。此外,我需要区分左手或右手三指滑动。

在我添加mapview之前,我正在尝试使用touchesMoved等。由于我发现这是不准确的,我转而使用UISwipegestureRecognizer,效果很好。

无论如何,一旦我添加了Map,它就会吃掉所有的东西。所以我一直在寻找答案。

这个看起来很有希望:

Intercepting/Hijacking iPhone Touch Events for MKMapView

以及子类化UIWindow并拦截触摸。

嗯,事实证明,它们都不适合我,因为在这两种情况下我最终都在

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

或在识别触摸类型等的情况下 这就是我第一次尝试做的事情!

所以我的问题是:有没有办法按照我上面描述的方式使用UIGestureRecognizers来维护我的控件,同时保持Mapview的功能?

我是否已经足够准确地描述了我的问题?

格尔茨。

4 个答案:

答案 0 :(得分:1)

This answer描述了对手势识别器进行子类化,以确保它不会干扰其他识别器。

您可以向MKMapView添加一个自定义识别器,拦截三个手指滑动(并做出适当的反应),然后允许所有其他手势由MKMapView正常处理。

上面的链接给出了通过子类化UIGestureRecognizer添加简单手指按下的示例。对于三指滑动,我会继承UISwipeGestureRecognizer。

我已成功使用此方法将两个手指旋转添加到MKMapView而不会弄乱平移和缩放等。

答案 1 :(得分:1)

地图不应该“吃掉”所有的触摸。这有点不对劲 - 我已经成功地将长按和敲击识别器添加到MKMapView中,并且它们按预期工作。

确保为您的控制器分配您创建的所有手势识别器的代理,并确保实施该方法:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer  shouldRecognizeSimultaneouslyWithGestureRecognizer :(UIGestureRecognizer *)otherGestureRecognizer;

您可以通过实施

获得进一步控制
 -(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer;

在此之后,非常依赖于您的实现细节,以使手势识别器与地图视图一起工作。根据我的经验,你可以添加自己的,它不应该干扰你的识别器。

其他一些想法: - 在MKMapView上叠加一个不可见的用户交互启用视图,以从中获取事件。根据您在地图视图上需要多少交互,您可以打开和关闭此等等。 - 将另一个滑动识别器添加到地图视图本身(除了父视图上的滑动识别器之外)。

你也可以玩UIView hitTest方法但对我来说总是太低了。

答案 2 :(得分:0)

问题很老,但是很实际。我的两分钱,特别是对于OSX 如果您需要通过代码检测区域变化中的挤压情况,请执行以下操作: (我设置了一个ivar来检测控制器代码的其他位置)

 func mapView(_ mapView: MKMapView, regionWillChangeAnimated animated: Bool) {
        guard let view = mapView.subviews.first else{ return }

        self.regionChangeIsFromUserInteraction = false

        #if os(iOS)
        guard let recognizers = view.gestureRecognizers else{ return }
        #elseif os(OSX)
        // on OSX they are in maps..
        let recognizers = mapView.gestureRecognizers
        #endif

        for recognizer : AimGestureRecognizer in recognizers{
            let state = recognizer.state
            if state == .began || state == .ended {
                self.regionChangeIsFromUserInteraction = true
                break
            }
        }

        #if DEBUG
        print("regionChangeIsFromUserInteraction ", self.regionChangeIsFromUserInteraction)
        #endif
    }

答案 3 :(得分:-3)

从MkMapView中删除滑动手势识别器会解决问题吗?

UISwipeGestureRecognizer *leftSwipeGesture = [[UISwipeGestureRecognizer alloc] init];
UISwipeGestureRecognizer *rightSwipeGesture = [[UISwipeGestureRecognizer alloc] init];

leftSwipeGesture.direction = UISwipeGestureRecognizerDirectionLeft;
rightSwipeGesture.direction = UISwipeGestureRecognizerDirectionRight;

[YourMKMapView removeGestureRecognizer:leftSwipeGesture];
[YourMKMapView removeGestureRecognizer:rightSwipeGesture];

这样,MKMapView将不会响应滑动手势并将响应者重新分配给MKMapView的容器视图控制器。