谷歌地图iOS didTapInfoWindowOfMarker在其他标记之上未触发

时间:2013-05-23 07:00:43

标签: ios google-maps infowindow google-maps-sdk-ios

我正在使用最新的GoogleMaps-iOS v1.3 SDK。

我在使用didTapInfoWindowOfMarker触发信息窗口点击时遇到问题,当它后面还有多个其他标记时。相反,更频繁地点击信息窗口,就好像在其后面点击标记(并打开不同的信息窗口)一样。

特别是,在我的地图上,我有几十个和几十个GMSMarkers非常接近 - 足够接近任何信息窗口弹出窗口将覆盖多个标记,即使在最高缩放级别。

有没有办法强制点击信息窗口上的点按钮,然后点击它后面的标记呢?

5 个答案:

答案 0 :(得分:2)

这可能不是最好的解决方案,似乎有点倒退,特别是有很多标记,但它应该有效。

在地图视图委托中,设置您的委托:

-(BOOL)mapView:(GMSMapView *)mapView didTapMarker:(GMSMarker *)marker 
{
    for (int x = 0; x < myMapView.markers.count; x++) 
    { 
        GMSMarker * tempMarker = myMapView.markers[x]; 
        tempMarker.tappable = NO; 
    }
    mapView.selectedMarker = marker; 
    return YES; 
}

然后你必须设置另一个委托方法:

- (void)mapView:(GMSMapView *)mapView didTapAtCoordinate:(CLLocationCoordinate2D)coordinate 
{
    for (int x = 0; x < myMapView.markers.count; x++) 
    { 
        GMSMarker * tempMarker = myMapView.markers[x]; 
        tempMarker.tappable = YES; 
    } 
}

我设置了这个,如果用户点击屏幕外,它将关闭信息窗口并重新启用标记的“tappability”。我知道这不是最好的方式,但是,考虑到你的情况,你可能没有选择。

我的建议是,如果您的屏幕上也有过多的标记,也许您可​​以将其设置为仅通过可见区域属性取消屏幕标记(将其添加到您的点击标记委托)

-(BOOL)mapView:(GMSMapView *)mapView didTapMarker:(GMSMarker *)marker
{
    GMSVisibleRegion myVisibleRegion = mapView.projection.visibleRegion;
    GMSCoordinateBounds * currentBounds = [[GMSCoordinateBounds alloc]initWithRegion:myVisibleRegion];
    for (int x = 0; x < myMapView.markers.count; x++) {
        if ([currentBounds containsCoordinate:marker.position]) {
            GMSMarker * tempMarker = myMapView.markers[x];
            tempMarker.tappable = NO;
        }
    }
    return NO;
}

然后只需获取那些边界内的标记。

如果您这样做,请在点按标记委托中将其设置为

- (void)mapView:(GMSMapView *)mapView didTapAtCoordinate:(CLLocationCoordinate2D)coordinate
{ 
    for (int x = 0; x < myMapView.markers.count; x++) {
        GMSMarker * tempMarker = myMapView.markers[x];
        if (tempMarker.tappable == NO) {
            tempMarker.tappable = YES;
        }
    }
}

这样,它只会更改当前无法点击的标记。

希望这有帮助!

答案 1 :(得分:2)

目前,我发现这是最好的解决方法:

https://github.com/ryanmaxwell/GoogleMapsCalloutView

基本上,返回一个零大小的UIView - (UIView *)mapView:markerInfoWindow:所以没有可见的“google maps infowindow”,并利用这个机会在MapView上创建并添加一个自定义UIView时间。在mapView:didChangeCameraPosition中,可以移动UIView以跟踪地图移动时的标记。

编辑:这也有一个好处,你可以拥有真实的,交互式的UIViews。 (而且,SMCalloutView看起来比googlemaps SDK中的默认infoWindow要好得多)

答案 2 :(得分:2)

对于此线程的未来读者的参考,此问题已在2013年7月的1.4.0版中得到解决。在发行说明中,在已解决的问题列表下,可以找到:

信息窗口不再允许点击通过

答案 3 :(得分:1)

这是在地图上调整您选择的标记位置的方法,以及在您的自定义视图背后的禁用标记。这些都不是一个尺寸适合所有,你需要调整您的规格。任何额外的高度欢迎。 。 。

享受!

金牛座。 。我无法确切地告诉你如何为你的情况做这件事;但是,我可以给你看看我的代码:

首先,我调整地图,使标记位于比中心更理想的位置。 。 。

(重要的是要注意,这需要北方轴承,如果您允许用户旋转地图,则必须相应调整)

只要缩放保持不变,您就可以将调整要求存储在变量中并使用相同的

- (void) adjustDisplayForImage: (GMSMarker *) marker
{
    // GET AN OFFSET AMOUNT IN DEGREES IN ORDER TO PROPERLY PLACE THE MARKER ACCORDING TO ZOOM

    CGPoint topLeft = CGPointMake(0, 0);
    CGRect screenRect = [[UIScreen mainScreen]bounds];
    CGPoint lowerLeft = CGPointMake(0, screenRect.size.height);

    CLLocationCoordinate2D topLeftCoordinate = [myMapView.projection coordinateForPoint:topLeft];
    CLLocationCoordinate2D lowerLeftCoordinate = [myMapView.projection coordinateForPoint:lowerLeft];

    CGFloat screenDistanceInDegreesLatitude = topLeftCoordinate.latitude - lowerLeftCoordinate.latitude;
    CGFloat adjustmentDistanceInDegreesLatitude = screenDistanceInDegreesLatitude / 2.8;
    // this is the amount that the new center needs to be offset in order to orient marker on screen

    // these are CLLocationDegrees variables, declared elsewhere
    adjustedLatitudeDegrees = marker.position.latitude + adjustmentDistanceInDegreesLatitude;

    adjustedLatitudeDegrees = marker.position.latitude + adjustmentDistanceInDegreesLatitude;

    CLLocationCoordinate2D newCenterCoordinate = CLLocationCoordinate2DMake(adjustedLatitudeDegrees, marker.position.longitude);

    myMapView.selectedMarker = marker;
    [myMapView animateToLocation:newCenterCoordinate];

    // I'm saving the current zoom so I don't have to get my adjustment distances again unless zoom changes
    lastZoom = myMapView.zoom;
}

好的,现在我有了这些信息,让我们删除我们观点背后的标记。 。 。

- (void) disableMarkersBehindView
{
    // my marker window is 213 x 280

    int markerWindowHeight = 280;
    int markerWindowWidth = 213;
    int approximateMarkerHeight = 10;

    // I'm just guessing here for marker height, whatever your marker's height is, use that

    // because of my adjustment, the marker position is adjusted about down 35% from the middle

    CGFloat adjustedDistanceInCGPoints =  myMapView.frame.size.height * (1 / 2.7);

    // This is because the marker defaults to the middle of the screen
    CGFloat middleY = myMapView.frame.size.height / 2;
    CGFloat newMarkerPositionY = middleY + adjustedDistanceInCGPoints;

    CGFloat topOfMarkerWindowY = newMarkerPositionY - markerWindowHeight - approximateMarkerHeight;

    // now we need a NorthEast and a SouthWest coordinate

    // NORTHEAST

    CGFloat halfWidth = myMapView.frame.size.width / 2;
    CGFloat northEastX = halfWidth - (markerWindowWidth / 2);

    CGPoint northEastCGPoint = CGPointMake(northEastX, topOfMarkerWindowY);

    CLLocationCoordinate2D northEastCoordinate = [myMapView.projection coordinateForPoint:northEastCGPoint];

    // SOUTHWEST

    CGFloat southWestX = halfWidth + (markerWindowWidth / 2);
    CGPoint southWestCGPoint = CGPointMake(southWestX, newMarkerPositionY);

    CLLocationCoordinate2D southWestCoordinate = [myMapView.projection coordinateForPoint:southWestCGPoint];

    // Now, make a boundary

    GMSCoordinateBounds * myViewBounds = [[GMSCoordinateBounds alloc]initWithCoordinate: northEastCoordinate coordinate:southWestCoordinate];

    for (int x = 0 ; x < myMapView.markers.count ; x++) {

        GMSMarker * marker = myMapView.markers[x];
        if ([myViewBounds containsCoordinate:marker.position]) {
            marker.tappable = NO;
            // here maybe add the markers to a seperate array so you can quickly make them tappable again wherever you need to
        }
    }
}

这考虑了各种缩放级别,如果你在地图上限制缩放,你可以简化它。

请记住让你的标记再次点击,这就是为什么我建议将它们保存在一个单独的数组中

不要忘记,调整仅基于北方轴承,禁用旋转轴承,使用

myMapView.settings.rotateGestures = NO;

如果没有,请务必先将地图重新​​定向到北方或做一些MATH!

- 希望这有帮助!

答案 4 :(得分:0)

这就是我的方式。设置mapview.delegate = self

你的.h文件

#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#import <GoogleMaps/GoogleMaps.h>

@interface MapViewController : UIViewController <CLLocationManagerDelegate, GMSMapViewDelegate>

@end

.m文件的viewDidLoad

    - (void)viewDidLoad {
        [super viewDidLoad];

        GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:40.124291
                                                                longitude:-104.765625
                                                                     zoom:2];
        mapView_ = [GMSMapView mapWithFrame:CGRectZero camera:camera];
        mapView_.myLocationEnabled = YES;
        self.view = mapView_;
        mapView_.delegate = self;
    }

#pragma mark - set current location
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{

}

#pragma mark - mapview events
-(BOOL) mapView:(GMSMapView *)mapView didTapMarker:(GMSMarker *)marker{
    NSLog(@"%@", marker.description);
//    show info window
    [mapView_ setSelectedMarker:marker];
    return YES;
}

-(void)mapView:(GMSMapView *)mapView didTapInfoWindowOfMarker:(GMSMarker *)marker{
    NSLog(@"info window tapped");
}