【问题标题】:Custom annotation view in Google Maps SDKGoogle Maps SDK 中的自定义注释视图
【发布时间】:2013-03-07 09:16:03
【问题描述】:

我创建了一个基于地图的 iOS 应用程序,我想在其中使用 Google Maps SDK for iOS 而不是 Mapkit,我找到了文档,但我没有找到与自定义注释视图相关的方法,谁能提供我的解决方案了解如何创建自定义注释视图(信息窗口)以及如何为其添加内容(标题,sn-p)。

【问题讨论】:

  • 不可能的 AFAICS。接受的答案表明自定义视图可以用作标注视图

标签: google-maps-sdk-ios


【解决方案1】:

我不了解你们,但我发现 Google 呈现的 UIView 信息窗口有点限制。使用SMCalloutViewRyan Maxwell's example project,可以呈现更多交互视图。

截至 2014 年 6 月 10 日,这适用于 Google Maps SDK v1.8.1。

首先,做一些设置:

#import <SMCalloutView/SMCalloutView.h>

static const CGFloat CalloutYOffset = 10.0f;

@interface ViewController ()
@property (strong, nonatomic) SMCalloutView *calloutView;
@property (strong, nonatomic) UIView *emptyCalloutView;
@end

初始化SMCalloutView,为其添加一个按钮,然后创建一个空的UIView

- (void)viewDidLoad
{
    /* all your other view init, settings, etc... */

    self.calloutView = [[SMCalloutView alloc] init];
    self.calloutView.hidden = YES;

    UIButton *button = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
    [button addTarget:self
               action:@selector(calloutAccessoryButtonTapped:)
     forControlEvents:UIControlEventTouchUpInside];
    self.calloutView.rightAccessoryView = button;

    self.emptyCalloutView = [[UIView alloc] initWithFrame:CGRectZero];
}

我们必须绘制那个空的 UIView 以满足 Maps SDK,但我们将显示的视图是 SMCalloutView。我还为标注视图设置了可重复使用的垂直偏移量。

添加委托方法来处理信息窗口调用:

#pragma mark - GMSMapViewDelegate

- (UIView *)mapView:(GMSMapView *)mapView markerInfoWindow:(GMSMarker *)marker {
    CLLocationCoordinate2D anchor = marker.position;

    CGPoint point = [mapView.projection pointForCoordinate:anchor];

    self.calloutView.title = marker.title;

    self.calloutView.calloutOffset = CGPointMake(0, -CalloutYOffset);

    self.calloutView.hidden = NO;

    CGRect calloutRect = CGRectZero;
    calloutRect.origin = point;
    calloutRect.size = CGSizeZero;

    [self.calloutView presentCalloutFromRect:calloutRect
                                      inView:mapView
                           constrainedToView:mapView
                                    animated:YES];

    return self.emptyCalloutView;
}

- (void)mapView:(GMSMapView *)pMapView didChangeCameraPosition:(GMSCameraPosition *)position {
    /* move callout with map drag */
    if (pMapView.selectedMarker != nil && !self.calloutView.hidden) {
        CLLocationCoordinate2D anchor = [pMapView.selectedMarker position];

        CGPoint arrowPt = self.calloutView.backgroundView.arrowPoint;

        CGPoint pt = [pMapView.projection pointForCoordinate:anchor];
        pt.x -= arrowPt.x;
        pt.y -= arrowPt.y + CalloutYOffset;

        self.calloutView.frame = (CGRect) {.origin = pt, .size = self.calloutView.frame.size };
    } else {
        self.calloutView.hidden = YES;
    }
}

- (void)mapView:(GMSMapView *)mapView didTapAtCoordinate:(CLLocationCoordinate2D)coordinate {
    self.calloutView.hidden = YES;
}

- (BOOL)mapView:(GMSMapView *)mapView didTapMarker:(GMSMarker *)marker {
    /* don't move map camera to center marker on tap */
    mapView.selectedMarker = marker;
    return YES;
}

手柄触摸标注按钮,此处使用带有标记标题和 sn-p 的警报视图:

- (void)calloutAccessoryButtonTapped:(id)sender {
    if (mapView_.selectedMarker) {
        GMSMarker *marker = mapView_.selectedMarker;
        //NSDictionary *userData = marker.userData;

        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:marker.title
                                                            message:marker.snippet
                                                           delegate:nil
                                                  cancelButtonTitle:@"OK"
                                                  otherButtonTitles:nil];
        [alertView show];
    }
}

显然,确保您的 ViewController(.h) 监听 GMSMapViewDelegate:

@interface ViewController : UIViewController <GMSMapViewDelegate>

这应该基本上可以工作。有关完整的 xcode 项目,请参阅 Ryan Maxwell 的上述example

【讨论】:

  • 还需要包含这一行:self.calloutView = [[SMCalloutView alloc] init];还有: self.emptyCalloutView = [[UIView alloc] initWithFrame:CGRectZero];在 viewDidLoad()
  • 糟糕,我回去添加了viewDidLoad初始化。谢谢@Zhang!
  • 最好也让其他人知道,如果你想在整个标注视图上添加点击,有一个协议委托方法你可以简单地实现,-(void)calloutViewClicked:(SMCalloutView *)calloutView符合的协议是:SMCalloutViewDelegate
  • @friedbunny 我知道这篇文章已经有 2 年的历史了,但是有没有关于这个正在为 swift 开发的消息?我正在努力寻找东西。
【解决方案2】:

如果您在 GoogleMaps.Framework 中检查 GMSMapView.h,您可以看到下面的方法,它可以让您为标记添加自定义信息窗口,而不是单独使用标准标题和 sn-p:

请注意(操作)说 annotationView=infoWindow
但是 NORMAL:annotationView = 标记本身和 calloutView = infoWindow

/**
 * Called when a marker is about to become selected, and provides an optional
 * custom info window to use for that marker if this method returns a UIView.
 * If you change this view after this method is called, those changes will not
 * necessarily be reflected in the rendered version.
 *
 * The returned UIView must not have bounds greater than 500 points on either
 * dimension.  As there is only one info window shown at any time, the returned
 * view may be reused between other info windows.
 *
 * @return The custom info window for the specified marker, or nil for default
 */
- (UIView *)mapView:(GMSMapView *)mapView
    markerInfoWindow:(id<GMSMarker>)marker;

【讨论】:

  • 注释视图不会在单击时显示,但始终显示。这更像是一个标注视图
  • 也许我误解了你,@Daij-Djan,但苹果似乎称之为"annotation view",谷歌称之为"info window"
  • 不,不要 - 但操作确实:) 正常:annotationView = 标记本身和 calloutView = infoWindow 但操作混合了它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多