将平移手势传递给 MKMapView

Posted

技术标签:

【中文标题】将平移手势传递给 MKMapView【英文标题】:Passing a pan gesture on to a MKMapView 【发布时间】:2017-10-07 17:03:21 【问题描述】:

编辑:将使我想要实现的目标更加清晰。

我在 MKMapView 上有一些注释,我想让它们易于拖动。移动注释的标准 Apple 方法是点击一次,然后快速点击并按住并拖动。该应用的用户抱怨这样做太难了。

所以从技术上讲,我想做的是使用平移手势。问题是 MKMapView 也在使用平移手势来移动地图。

我想要做的是当用户进行平移手势时,检查平移手势是否开始真正靠近注释,如果是,则让平移手势处理程序移动注释。我有这部分工作。

但是,如果平移手势不靠近注释,则将手势传递给 MKMapView 以供其处理。

// 编辑结束

我有一种处理平移手势的方法。当 MKMapView 上有平移手势时,这会被调用。有时我不想在我的方法中处理手势,而是将手势传递给 MKMapView 以正常平移/拖动地图。

这是我到目前为止所获得的概要。 该方法正在处理平移手势:

-(void)panGesture:(UIPanGestureRecognizer*)sender

根据某些逻辑,我想将此手势传递给 MKMapView (self.mapView)。 有人可以分享一下代码吗?

我尝试了[self.mapView gestureRecognizerShouldBegin:sender];,但这次通话没有任何反应。

- (void) addPanGesture

    self.panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGesture:)];
    self.panGesture.delegate = self;
    [self.panGesture setMinimumNumberOfTouches:1];
    [self.panGesture setMaximumNumberOfTouches:1];
    [self.mapView addGestureRecognizer:self.panGesture];



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

    return YES;


- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer

    BOOL result = NO;
    if ((gestureRecognizer == self.panGesture) && [[otherGestureRecognizer view] isDescendantOfView:[gestureRecognizer view]])
    
        result = YES;
    
    return result;


-(void)panGesture:(UIPanGestureRecognizer*)sender

    //some logic to see if we will handle the gesture in this method or pass gesture on to the MKMapView

    return;

【问题讨论】:

如果不覆盖 MKMapView 伴侣的平移手势,我认为您无法做到这一点。 抱歉,还是不清楚你想要什么,能详细点吗? @iPatel 进行了编辑以澄清 您可以尝试在 MKAnnotationView 上添加平移手势,因为每个注释都有一个视图 【参考方案1】:

移动注释的标准 Apple 方法是点击一次,然后快速点击并按住并拖动。该应用的用户抱怨这样做太难了。

我不这么认为.. :(

我要写我的逻辑,实际上使用平移手势是一件坏事,即使苹果提供了默认的拖放功能。顺便说一句,如果您按照问题中提到的方式进行操作,那么您必须为地图上显示的每个注释添加单独的平移手势。添加它自己的标签并为所有人保留相同的手势方法名称,以便您可以轻松地通过标签管理它。因此,当最终用户点击/触摸任何注释时,它的方法将被调用,您可以通过它自己的标签获得触摸/点击的注释。仅为拖放注释编写代码。不确定,但可能会解决您的问题。

【讨论】:

【参考方案2】:

我完全同意 iPatel:如果可能,应该使用标准的 Apple 方式,因为用户已经习惯了。 但是,如果您真的想实现自己的解决方案,也许以下方法可能有效(未经测试):

MapView 有一个内置的PanGestureRecognizer(这里称为builInPGR)。我假设您将自己的PanGestureRecognizer(此处称为ownPGR)添加到此MapView。 现在UIGestureRecognizerDelegate 协议中的以下函数控制两个手势识别器是否应该同时识别(参见docs):

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, 
shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool

默认实现返回false

您提到可以使用ownPGR 拖动注释。这意味着builInPGR 确实ownPGR 同时识别平移手势。

如果你现在实现这个委托函数并返回trueownPGRbuilInPGR 应该同时工作:builInPGR 将移动地图,ownPGR 将检查靠近注释的区域是否有被点击,如果是,将移动注释。

现在,这个委托函数还为您提供了一个指向 builInPGR 的指针,即 otherGestureRecognizer。 因此,如果ownPGR 决定拖动注释,因为它开始靠近它,您可以将builInPGR 的属性isEnabled 设置为false。这让builInPGR 转换到取消状态,并且地图将不再被拖动。 当然,当ownPGR 完成拖动注释时,您必须再次将builInPGR.isEnabled 设置为true

再说一遍:我不知道这是否有效,但它可能会。我强烈建议使用标准方法!

编辑:对不起,我刚刚意识到你想要 Obj-C 中的答案。但是,使用文档(只需切换到 Obj-C)应该很容易在 Obj-C 中测试它。

【讨论】:

以上是关于将平移手势传递给 MKMapView的主要内容,如果未能解决你的问题,请参考以下文章

如何将控制从一个手势识别器传递给另一个

如何将平移手势从滚动视图转发到另一个滚动视图

平移手势不会将触摸转发到 Mapbox MGLMapView

将平移手势识别器限制为特定圆圈

将平移手势限制为设置帧

将平移手势添加到 UICollectionView 单元 - IOS/Swift