自定义MKAnnotation标注视图? [英] Customize MKAnnotation Callout View?

查看:107
本文介绍了自定义MKAnnotation标注视图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有 MKPointAnnotation

 让ann = MKPointAnnotation( )
self.ann.coordinate = annLoc
self.ann.title =自定义我
self.ann.subtitle =???
self.mapView.addAnnotation(ann)

看起来像这样:





如何自定义此标注视图以创建我自己的视图而不是预定义的视图?

解决方案

首先应该注意的是,通过简单地调整系统提供的callout的属性,然后自定义左右附件(通过 rightCalloutAccessoryView leftCalloutAccessoryView )。您可以在 viewForAnnotation 中进行该配置。



在iOS 9中,我们现在可以访问 detailCalloutAccessoryView ,用潜在的替换标注的副标题视觉丰富的视图,同时仍然享受标注气泡的自动再现(使用自动布局使这更容易)。



例如,这是一个使用 MKSnapshotter 来提供详细图像视图图像的标注WWDC 2015视频中展示的标注配件



您可以通过以下方式实现此目的:

  func mapView(mapView:MKMapView,viewForAnnotation annotation:MKAnnotation) - > MKAnnotationView? {
如果注释是MKUserLocation {
return nil
}

let identifier =MyCustomAnnotation

var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(标识符)
如果annotationView == nil {
annotationView = MKPinAnnotationView(annotation:annotation,reuseIdentifier:identifier)
annotationView?.canShowCallout = true
} else {
annotationView !.annotation = annotation
}

configureDetailView(annotationView!)

return annotationView
}

func configureDetailView(annotationView :MKAnnotationView){
let width = 300
let height = 200

let snapshotView = UIView()
let views = [snapshotView:snapshotView]
snapshotView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat(H:[snapshotView(300)],options:[],metrics:nil,views:views))
snapshotView.addConst raints(NSLayoutConstraint.constraintsWithVisualFormat(V:[snapshotView(200)],options:[],metrics:nil,views:views))

let options = MKMapSnapshotOptions()
options .size = CGSize(宽度:宽度,高度:高度)
options.mapType = .SatelliteFlyover
options.camera = MKMapCamera(lookingAtCenterCoordinate:annotationView.annotation!.coordinate,fromDistance:250,pitch:65,标题:0)

let snapshotter = MKMapSnapshotter(选项:选项)
snapshotter.startWithCompletionHandler {快照,如果快照错误在
!= nil {
让imageView = UIImageView(框架:CGRect(x:0,y:0,宽度:宽度,高度:高度))
imageView.image = snapshot!.image
snapshotView.addSubview(imageView)
}
}

annotationView.detailCalloutAccessoryView = snapshotView
}



<如果你正在寻找更加彻底的卡洛重新设计或者需要支持9之前的iOS版本,需要更多的工作。该过程需要(a)禁用默认标注; (b)当用户点击现有的注释视图(即地图上的视觉图钉)时添加您自己的视图。



然后设计中出现了复杂性标注,您必须绘制您想要的所有内容。例如。如果你想绘制一个气泡以产生呼唤的弹出感觉,你必须自己做。但是如果熟悉如何绘制形状,图像,文本等,您应该能够渲染一个能够实现所需UX的标注:





只需将视图添加为注释视图本身的子视图,并相应地调整其约束:

  func mapView(mapView:MKMapView,didSelectAnnotationView视图:MKAnnotationView){
让calloutView = ...
calloutView.translatesAutoresizingMaskIntoConstraints = false
calloutView.backgroundColor = UIColor。 lightGrayColor()
view.addSubview(calloutView)

NSLayoutConstraint.activateConstraints([
calloutView.bottomAnchor.constraintEqualToAnchor(view.topAnchor,constant:0),
calloutView .widthAnchor.constraintEqualToConstant(60),
calloutView.heightAnchor.constraintEqualToConstant(30),
calloutView.centerXAnchor.constraintEqualToAnchor(view.centerXAnchor,constant:view.calloutOffset.x)
])
}

有关创建自己的标注的示例,请参见 https://github.com/robertmryan/CustomMapViewAnnotationCalloutSwift 视图。这只会添加两个标签,但它说明了这样一个事实:你可以绘制任何你想要的形状的气泡,使用约束来决定标注的大小等等。


I have a MKPointAnnotation:

let ann = MKPointAnnotation()
self.ann.coordinate = annLoc
self.ann.title = "Customize me"
self.ann.subtitle = "???"
self.mapView.addAnnotation(ann)

It looks like this:

How can I customize this callout view to create my own view instead of the predefined one?

解决方案

It should first be noted that the simplest changes to the callout are enabled by simply adjusting the properties of the system provided callout, but customizing the right and left accessories (via rightCalloutAccessoryView and leftCalloutAccessoryView). You can do that configuration in viewForAnnotation.

In iOS 9, we now have access to the detailCalloutAccessoryView which, replaces the subtitle of the callout with a potentially visually rich view, while still enjoying the automatic rendition of the callout bubble (using auto layout makes this easier).

For example, here is a callout that used a MKSnapshotter to supply the image for an image view in the detail callout accessory as demonstrated in WWDC 2015 video What's New in MapKit:

You can achieve this with something like:

func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
    if annotation is MKUserLocation {
        return nil
    }

    let identifier = "MyCustomAnnotation"

    var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(identifier)
    if annotationView == nil {
        annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
        annotationView?.canShowCallout = true
    } else {
        annotationView!.annotation = annotation
    }

    configureDetailView(annotationView!)

    return annotationView
}

func configureDetailView(annotationView: MKAnnotationView) {
    let width = 300
    let height = 200

    let snapshotView = UIView()
    let views = ["snapshotView": snapshotView]
    snapshotView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:[snapshotView(300)]", options: [], metrics: nil, views: views))
    snapshotView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:[snapshotView(200)]", options: [], metrics: nil, views: views))

    let options = MKMapSnapshotOptions()
    options.size = CGSize(width: width, height: height)
    options.mapType = .SatelliteFlyover
    options.camera = MKMapCamera(lookingAtCenterCoordinate: annotationView.annotation!.coordinate, fromDistance: 250, pitch: 65, heading: 0)

    let snapshotter = MKMapSnapshotter(options: options)
    snapshotter.startWithCompletionHandler { snapshot, error in
        if snapshot != nil {
            let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: width, height: height))
            imageView.image = snapshot!.image
            snapshotView.addSubview(imageView)
        }
    }

    annotationView.detailCalloutAccessoryView = snapshotView
}

If you're looking for a more radical redesign of the callout or need to support iOS versions prior to 9, it takes more work. The process entails (a) disabling the default callout; and (b) adding your own view when the user taps on the existing annotation view (i.e. the visual pin on the map).

The complexity then comes in the design of the callout, where you have to draw everything you want visible. E.g. if you want to draw a bubble to yield the popover feel of the call out, you have to do that yourself. But with some familiarity with how to draw shapes, images, text, etc., you should be able to render a callout that achieves the desired UX:

Just add the view as a subview of the annotation view itself, and adjust its constraints accordingly:

func mapView(mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView) {
    let calloutView = ...
    calloutView.translatesAutoresizingMaskIntoConstraints = false
    calloutView.backgroundColor = UIColor.lightGrayColor()
    view.addSubview(calloutView)

    NSLayoutConstraint.activateConstraints([
        calloutView.bottomAnchor.constraintEqualToAnchor(view.topAnchor, constant: 0),
        calloutView.widthAnchor.constraintEqualToConstant(60),
        calloutView.heightAnchor.constraintEqualToConstant(30),
        calloutView.centerXAnchor.constraintEqualToAnchor(view.centerXAnchor, constant: view.calloutOffset.x)
    ])
}

See https://github.com/robertmryan/CustomMapViewAnnotationCalloutSwift for an example of creating your own callout view. This only adds two labels, but it illustrates the fact that you can draw the bubble any shape you want, use constraints to dictate the size of the callout, etc.

这篇关于自定义MKAnnotation标注视图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆