当前位置: 首页 > 面试题库 >

自定义MKAnnotation标注视图?

郑高驰
2023-03-14
问题内容

我有一个 MKPointAnnotation:

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

问题答案:

首先应注意,通过简单地调整系统提供的标注的属性,但
自定义左右附件(通过rightCalloutAccessoryView和leftCalloutAccessoryView),就可以对标注进行最简单的更改。您可以在中进行配置viewForAnnotation。

从iOS 9开始,我们可以使用detailCalloutAccessoryViewwhich来用可能具有丰富视觉效果的视图替换标注的字幕,同时仍然享受标注气泡的自动呈现(使用自动布局可使此操作变得更容易)。

例如,这是一个标注,用于 在细节标注附件中为图像视图MKSnapshotter提供图像
,如WWDC 2015视频 MapKit 的新增功能

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

class SnapshotAnnotationView: MKPinAnnotationView {
    override var annotation: MKAnnotation? { didSet { configureDetailView() } }

    override init(annotation: MKAnnotation?, reuseIdentifier: String?) {
        super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
        configure()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        configure()
    }
}

private extension SnapshotAnnotationView {
    func configure() {
        canShowCallout = true
        configureDetailView()
    }

    func configureDetailView() {
        guard let annotation = annotation else { return }

        let rect = CGRect(origin: .zero, size: CGSize(width: 300, height: 200))

        let snapshotView = UIView()
        snapshotView.translatesAutoresizingMaskIntoConstraints = false

        let options = MKMapSnapshotter.Options()
        options.size = rect.size
        options.mapType = .satelliteFlyover
        options.camera = MKMapCamera(lookingAtCenter: annotation.coordinate, fromDistance: 250, pitch: 65, heading: 0)

        let snapshotter = MKMapSnapshotter(options: options)
        snapshotter.start { snapshot, error in
            guard let snapshot = snapshot, error == nil else {
                print(error ?? "Unknown error")
                return
            }

            let imageView = UIImageView(frame: rect)
            imageView.image = snapshot.image
            snapshotView.addSubview(imageView)
        }

        detailCalloutAccessoryView = snapshotView
        NSLayoutConstraint.activate([
            snapshotView.widthAnchor.constraint(equalToConstant: rect.width),
            snapshotView.heightAnchor.constraint(equalToConstant: rect.height)
        ])
    }
}

当然,您随后将在地图中注册该注释视图,并且完全
mapView(_:viewFor:)不需要:

mapView.register(SnapshotAnnotationView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier)

如果您希望对标注进行更彻底的重新设计,或者需要
支持9之前的iOS版本,则需要进行更多工作。该过程需要(a)
禁用默认标注;(b)当用户点击
现有注释视图(即地图上的可视图钉)时添加您自己的视图。

然后,标注的设计就变得很复杂,您必须在其中绘制想要显示的所有内容。例如,如果您想绘制气泡以产生呼出的弹出效果,则必须自己完成。但是,对于如何绘制形状,图像,文本等有所了解,您应该能够
渲染实现所需UX的标注:

自定义标注

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

func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
    let calloutView = ...
    calloutView.translatesAutoresizingMaskIntoConstraints = false
    calloutView.backgroundColor = UIColor.lightGray
    view.addSubview(calloutView)

    NSLayoutConstraint.activate([
        calloutView.bottomAnchor.constraint(equalTo: view.topAnchor, constant: 0),
        calloutView.widthAnchor.constraint(equalToConstant: 60),
        calloutView.heightAnchor.constraint(equalToConstant: 30),
        calloutView.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: view.calloutOffset.x)
    ])
}

见https://github.com/robertmryan/CustomMapViewAnnotationCalloutSwift为
创建自己的标注视图的一个例子。这仅添加了两个标签,但它说明了您可以绘制所需形状的气泡,使用
约束来指定标注大小等事实。



 类似资料:
  • 问题内容: 我正在添加这样的标注视图: 尽管我的函数从未被调用过……但我很好奇理解原因并获得了一些可以处理与标注视图交互的东西。 问题答案: 这是因为注释视图仅检测其边界内的触摸。由于您的标注视图超出了范围,因此子视图无法识别点击。您需要在注释视图中覆盖该方法,以便您的标注实际上可以检测到触摸。 这是Objective-C中的一个示例: 编辑 : 迅捷版:

  • 问题内容: 我要显示图像而不是小 别针 。 有人可以在这里放置一些有用的代码,或告诉它怎么做吗? 我希望我的图片 pinks.jpg 会显示在地图上,而不是默认的图钉视图( 石头图钉形状 ),而是固定位置。但是我仍然得到该引脚的默认图像。 问题答案: 如果要将自己的图像用于注释视图,则应创建一个,而不是。 是的子类,因此具有属性,但通常会覆盖该属性并绘制图钉图像(这就是它的作用)。 因此,将代码更

  • 在我的代码中,我使用下面的代码来设置表视图的节标题。它运行良好。 我想自定义标题的背景颜色,所以我在上面的代码之前插入了下面的代码。 结果,背景颜色发生变化,而标题文本丢失。

  • 问题内容: 我正在尝试在导航栏的中心添加自定义视图,并且正在使用以下代码对其进行测试: 我在视图控制器的viewDidLoad方法中进行设置,但是当我运行程序时,导航栏中似乎没有任何变化。 你能帮我吗? 问题答案: 这可行。初始化时给框架

  • 英文原文:http://emberjs.com/guides/views/customizing-a-views-element 视图在页面上表现为一个单一的DOM元素。通过修改tagName属性,可以改变视图生成的元素的类型。 1 2 3 App.MyView = Ember.View.extend({ tagName: 'span' }); 另外,还可以通过设置一个字符串数组到clas

  • 目前,诸葛io的服务范围涵盖了企业内各项业务,除了用户行为指标外,还有很多结合业务场景的特有指标需要分析;如:注册率=注册成功人数/活跃用户数,分、秒之间的单位换算等。 因此,诸葛io平台中提供了基础指标之间的四则运算,可灵活定义符合业务场景的特有指标,并支持自定义指标的可视化分析,以及将指标添加到数据看板中进行持续的跟踪监测的功能。 一、有哪些常见应用场景 场景一 某音频APP,需要统计人均收听