更新到SDK 1.3.1后,GMSMapView上的拖动/平移手势无法被捕获

5
我在通过手势识别器捕获GMSMapView上的拖动/平移手势时遇到了奇怪的问题。这个问题只出现在从GMS 1.2更新到1.3.1之后,其中(引用文档),

触摸被GMSMapView更积极地消耗。

我有一个UIViewController,在其主视图下持有一个GMSMapView。我发现GMSMapDelegate没有提供处理拖动/平移手势的方法,因此我向UIViewController添加了一个UIPanGestureRecognizer,将其链接到IBAction选择器,并设置引用输出和输出集合,如此处所示的屏幕截图:http://i.stack.imgur.com/gktoa.png 因此,任何拖动操作都会简单地触发下面的recognizeDragOnMap:选择器:
-(IBAction)recognizeDragOnMap:(id)sender {
    NSLog(@"recognizeDragOnMap");

    UIGestureRecognizer *gestureRecognizer = (UIGestureRecognizer *)sender;
    if (gestureRecognizer.state != UIGestureRecognizerStateEnded) {
        NSLog(@"Still dragging");
        return;
    }
    NSLog(@"DragEnded");

    GMSCameraPosition *position;

    if ((position = self.mapView.camera)) {
        self.automaticCameraPositionChange = NO;
        CLLocationCoordinate2D coordinate = [position targetAsCoordinate];
        CLLocation *location = [[CLLocation alloc] initWithLatitude:coordinate.latitude longitude:coordinate.longitude];
        [self.origin dragPinToLocation:location];
    } else {
        NSLog(@"No map camera");
    }
}

这个设置在GMS 1.2.0版本下运行得非常完美。但是在更新后,GMSMapView仍然像以前一样响应手势,但上述方法却没有被调用!有人知道怎么回事或如何修复吗?

非常谨慎,我进行了以下测试: 1)在另一个UIViewController上设置了一个等效的UIPanGestureRecognizer,没有GMSMapView...结果一切正常。 2)将我的项目还原到1.3.1之前的提交版本,也一切正常。 - Rafael Kaufmann
我知道mapView:didChangeCameraPosition:,但这并不足够:我需要能够区分由地图手势生成的相机更新和其他操作生成的相机更新。 - Rafael Kaufmann
6个回答

12
对于版本1.4或更高版本,您只需要在GMSUISettings对象中设置consumesGesturesInView = NO
如果您这样做,请注意您将不得不处理可能会使您的父视图执行操作的事件,而您只想与地图进行交互...我的意思是,例如,在滚动视图中添加了一个GMSMapView并拖动它时,将滚动滚动视图!

10
mapView.settings.consumesGesturesInView = YES;

也很有帮助。我父母的观念正在影响我的手势识别器。

再加上

for (UIGestureRecognizer *gestureRecognizer in mapView.gestureRecognizers) {
    [gestureRecognizer addTarget:self action:@selector(handlePan:)];
}


//////



-(IBAction) handlePan:(UIPanGestureRecognizer*)sender {



    if (sender.state == UIGestureRecognizerStateEnded) {
        CGSize size = mapView.frame.size;
        CGPoint tp = CGPointMake(size.width/2, size.height/2);
        CLLocationCoordinate2D loc = [mapView.projection coordinateForPoint:tp];
        [mapView animateToCameraPosition:[GMSCameraPosition cameraWithTarget:loc zoom:mapView.camera.zoom]];



    }


}

太棒了!而且你甚至不需要添加自己的pan手势识别器


太好了,我一直卡住了,都快把头发拔光了! - Siddhartha

3

事实证明,现在一个GMSMapView实例拥有一个GMSBlockingGestureRecognizer,它会吞噬所有手势。所以有两个选择:

  • 在加载GMSMapView后删除此识别器(可能会破坏依赖于它的内部功能)(像这样);或者
  • 将自己的目标/操作附加到识别器上。

采用第二种方法,以下代码放在UIViewControllerviewDidLoad中使一切恢复正常:

self.mapView = (RAMapView *)[self.view viewWithTag:1];

for (UIGestureRecognizer *gestureRecognizer in self.mapView.gestureRecognizers) {
    [gestureRecognizer addTarget:self action:@selector(recognizeDragOnMap:)];
}

老实说,这是一个丑陋、邪恶的补丁,但它确实有效。 :)

0
通过对 Google API 和其他方法的分析,我没有得到合适的答案。这个问题的最佳和简洁的答案是使用平移手势。
将平移手势添加到地图视图中:
self.mapView.settings.consumesGesturesInView = false
let panGesture = UIPanGestureRecognizer(target: self, action: #selector(self. panHandler(_:)))
self.mapView.addGestureRecognizer(panGesture)

实现平移手势方法

@objc private func panHandler(_ pan : UIPanGestureRecognizer){

        if pan.state == .ended{
            let mapSize = self.mapView.frame.size
            let point = CGPoint(x: mapSize.width/2, y: mapSize.height/2)
            let newCoordinate = self.mapView.projection.coordinate(for: point)
            print(newCoordinate)
             //do task here
        }
}

0
更好的选择是设置自己手势识别器的代理,然后添加以下代理方法:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    return YES;
}

然后它将像以前一样工作。


嘿,Ryan,我确实尝试过这个,但没有效果。似乎GMSBlockingGestureRecognizer非常激进! - Rafael Kaufmann

0

嘿,Google 地图中有一个委托方法。

- (void)mapView:(GMSMapView *)mapView    didTapAtCoordinate:(CLLocationCoordinate2D)coordinate;

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