【问题标题】:How To add custom View in map's Annotation's Callout's如何在地图注释标注中添加自定义视图
【发布时间】:2013-03-06 07:24:04
【问题描述】:

这是我的代码。我想添加我自己的自定义标注视图而不是 iOS 默认值。我知道只有左标注和右标注视图,但我需要添加一个带有我自己的背景和标签的视图工具提示类型。

    - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
    {
        MKAnnotationView *userAnnotationView = nil;
        if ([annotation isKindOfClass:MKUserLocation.class])
        {
            userAnnotationView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"UserLocation"];
            if (userAnnotationView == nil)  {
            userAnnotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"UserLocation"];
            }
            else
                userAnnotationView.annotation = annotation;

            userAnnotationView.enabled = YES;


            userAnnotationView.canShowCallout = YES;
            userAnnotationView.image = [UIImage imageNamed:@"map_pin.png"];
            UIView *view = [[UIView alloc]initWithFrame:CGRectMake(0,0,141,108)];
            view.backgroundColor = [UIColor clearColor];
            UIImageView *imgView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"toltip.png"]];
            [view addSubview:imgView];
            userAnnotationView.leftCalloutAccessoryView = view;



            return userAnnotationView;
        }

}

【问题讨论】:

标签: iphone maps


【解决方案1】:

我遇到了同样的问题,最后做了以下事情:

当我收到 mapView 委托回调时

-(void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view

(是时候展示我的自定义 CalloutView 了)

我使用作为参数接收的视图 *(MKAnnotationView )view(这是一个 pin 视图)并使用

简单地将我的自定义视图添加到该 pin 视图
 [view addSubview:customView];

它会将您的自定义视图添加到该引脚视图的顶部,因此如果我们希望它位于引脚上方,我们必须像这样更改自定义视图中心属性:

CGRect customViewRect = customView.frame;
        CGRect rect = CGRectMake(-customViewRect.size.width/2, -customViewRect.size.height-7, customViewRect.size.width, customViewRect.size.height);
        customView.frame = rect;
[view addSubview:customView];

就我而言,它看起来像这样

!注意

有一个警告可以轻松解决,您的 自定义视图将忽略触摸事件,因为 ma​​pView 以不同的方式处理触摸.这是一个快速修复

1) 子类 MKAnnotationView(或 MKPinAnnotationView 取决于您的需要)

2) 在您的 mapView 委托中

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation

使用您的子类而不是 MKAnnotationView/MKPinAnnotationView

3) 在您的子类 .m 文件中覆盖以下两个方法:

- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event
{
    UIView* hitView = [super hitTest:point withEvent:event];
    if (hitView != nil)
    {
        [self.superview bringSubviewToFront:self];
    }
    return hitView;
}

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)event
{
    CGRect rect = self.bounds;
    BOOL isInside = CGRectContainsPoint(rect, point);
    if(!isInside)
    {
        for (UIView *view in self.subviews)
        {
            isInside = CGRectContainsPoint(view.frame, point);
            if(isInside)
                break;
        }
    }
    return isInside;
}

全部完成!

【讨论】:

  • 太棒了!为什么不选择这个作为解决方案?
  • 像魅力一样工作,谢谢!你是怎么知道的?我花了很长时间摆弄框架和sizeToFit,但都没有奏效!
  • 什么是 visibleCalloutView ?
  • addSubview:customView.center = CGPointMake(view.bounds.size.width*0.5f, -self.visibleCalloutView.bounds.size.height*0.5f);在这个对象表示的方法“visibleCalloutView”中,我收到错误“在对象类型上找不到”,请帮助我。
  • @iPatel 这是因为添加的子视图超出了父视图的可见矩形。如果你在MKAnnotationView 上设置clipsToBounds,你甚至看不到添加的子视图。从iOS9开始,有一个detailCalloutAccessoryView可以自定义callout。
【解决方案2】:

我创建了一个库来显示自定义标注。

DXCustomCallout-ObjC

您可以为标注传递任何自定义视图! 它也支持 UIControls 的事件。

【讨论】:

  • 刚刚在 iOS 9 上使用过,目前看来还不错。
  • hi,在选择另一个注释时,如何隐藏标注? span>
  • @Misha 一个标注应该在选择另一个标注时自动隐藏。当标注太接近/重叠时,这种行为似乎存在一些问题。当我有时间时,我会尝试修复并推送更新。
  • 我也希望如此。但它不起作用。标注没有关闭。 :(
【解决方案3】:

以上 Swift 中的最佳答案

这可以节省一些时间来重写自己。

!注意:

有一个警告可以很容易地解决,您的自定义视图将忽略触摸事件,因为 mapView 以不同的方式处理触摸。这是一个快速修复:

1) 子类 MKAnnotationView(或 MKPinAnnotationView 取决于您的需要)

2) 在您的 mapView 委托中

func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView?

使用您的子类而不是 MKAnnotationView/MKPinAnnotationView

3) 在您的子类 .m 文件中覆盖以下两个方法:

override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? {

    let hitView = super.hitTest(point, withEvent: event)

    if (hitView != nil)
    {
        self.superview?.bringSubviewToFront(self)
    }

    return hitView;

}

override func pointInside(point: CGPoint, withEvent event: UIEvent?) -> Bool {

    let rect = self.bounds
    var isInside = CGRectContainsPoint(rect, point)

    if(!isInside) {
        for view in self.subviews {

            isInside = CGRectContainsPoint(view.frame, point)
            break;
        }
    }

    return isInside
}

【讨论】:

  • 我认为你的休息应该放在 if isInside {}
【解决方案4】:
【解决方案5】:

我刚刚为我的地图视图创建了一个自定义标注,以避免在点击时标注消失的问题。 Here 是我采取的步骤的要点。

【讨论】:

  • 我已经实现了你的代码,但它不起作用。你能帮帮我吗?
【解决方案6】:

你可以使用这个库。它还为标注视图提供了一个现成的模板。为您的自定义视图添加酷炫的动画和锚点视图。

https://github.com/okhanokbay/MapViewPlus

【讨论】:

    猜你喜欢
    • 2012-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多