自定义 MKAnnotation 标注视图?

2024-01-04

我有一个MKPointAnnotation:

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

它看起来像这样:

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


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

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

例如,这是一个使用了MKSnapshotter为详细标注附件中的图像视图提供图像,如 WWDC 2015 视频中所示MapKit 中的新功能 https://developer.apple.com/videos/play/wwdc2015-206/:

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

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) 当用户点击现有注释视图(即地图上的视觉图钉)时添加您自己的视图。

然后,复杂性就出现在标注的设计中,您必须在其中绘制您想要可见的所有内容。例如。如果你想画一个气泡来产生呼出的弹出窗口的感觉,你必须自己做。但是,如果熟悉如何绘制形状、图像、文本等,您应该能够渲染实现所需用户体验的标注:

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

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)
    ])
}

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

自定义 MKAnnotation 标注视图? 的相关文章

  • 无法构建 Saurik 的 ldid 实用程序

    当我执行此命令 make sh 时 我遇到这些错误 构建用于越狱调整开发的 ldid 实用程序 Bilals Mac ldid billy make sh g arch i386 arch x86 64 arch ppc arch armv
  • XMPPFramework - 如何创建多用户聊天室?

    我如何使用XMPPFramework在iPhone中实现GroupChat 我尝试了以下代码 但房间没有创建 我如何知道房间是否创建 XMPPRoomDelegate没有被调用 当Stream断开连接时 调用handleDidLeaveRo
  • 将永久字符添加到 UITextField

    有没有办法将字母永久添加到 UITextField 中 用户无法删除它 我想添加一个字符 用户无法删除它 但他们仍然可以在之后添加字母 Cheers 附注这是适用于 iOS 的 A UITextField有一个名为 应该更改范围内的字符 的
  • 从 UIImagePickerController 相机视图推送 viewController

    我正在开发一款消息应用程序 类似于 WhatsApp 用户可以互相发送文本和图像消息 当用户想要发送图像时 他可以从相机胶卷中选择一张图像 也可以用相机拍摄一张图像 这就是我介绍的方式UIImagePickerController对于这两种
  • 打乱 NSMutableArray 而不重复并显示在 UIButton 中

    在我看来 我有 12 个按钮 一个数组包含 6 个名称 我想在其中打印数组名称UIButton标题 这是我的代码 texts NSMutableArray alloc initWithObjects 1 2 3 4 5 6 nil UIBu
  • 确定 SceneKit 中 SKVideoNode 的视频大小/长宽比

    如何从 AVPlayer 获取视频的视频大小来设置节点的几何大小 例如 我有一个具有宽度和高度的 SCNPlane let planeGeo SCNPlane width 5 height 5 所以现在我实例化我的视频播放器 let vid
  • Parse.com 从相关 PFObject 获取 PFUser

    我正在将照片保存为 PFObject 解析 并使用 PFUser currentUser 用户 ID 作为其键之一 我想在表格视图中显示照片以及该 PFUser 的详细信息 但是当我尝试获取用户时 PFUser user self phot
  • 如何使用 NSUserDefaults 在 Swift 中存储自定义类的数组?

    我有一个名为的自定义类Person当某人输入信息时 它会存储有关某人的各种属性 class Person Person dictionary variable var name String var age String var html
  • GeoFire Swift 3 - 保存和更新坐标

    我正在尝试使用 GeoFire 将坐标存储到 Firebase 数据库中 我不确定如何更新新坐标 因为它们每秒都会更改 更新 随着childByAutoId 它正在为每辆自行车生成一个新的唯一 ID 如何引用这个唯一的自行车 ID 例如 用
  • 在 Xcode 5 中重命名 iOS 项目[重复]

    这个问题在这里已经有答案了 我需要重命名一个 iOS 项目 有没有办法在不开始一个全新项目的情况下做到这一点 我发现的所有其他信息都与 Xcode 4 或旧版本相关 这些方法似乎使项目崩溃 我在尝试任何名称更改之前创建了一个快照 在 Xco
  • 在 Swift 中从 UIScrollView 创建 PDF 文件

    我想从 UIScrollView 的内容创建一个 PDF 文件 func createPdfFromView aView UIView saveToDocumentsWithFileName fileName String let pdfD
  • 适用于 iPhone / iPad / iOS 的快速、精益 PDF 查看器 - 提示和提示?

    最近有很多关于绘制 PDF 的问题 是的 您可以使用UIWebView但这无法提供您所期望的优秀 PDF 查看器的性能和功能 您可以绘制PDF页面到 CALayer http www cocoabuilder com archive coc
  • 如何使用 Swift 使用 TouchID?

    Apple 为 iOS 8 的 TouchID 实现提供的文档采用 Objective C 语言 有 Swift 版本吗 Objective C IBAction touchIDAvailable UIButton touchIDAvail
  • 减少 CoreData 的调试输出?

    我正在开发一个使用 CoreData 的 iOS macOS 项目 它工作正常 但它会向控制台输出大量调试信息 这使得控制台无法使用 因为我的打印语句隐藏在所有与 CoreData 相关的内容中 我有一个非常简单的 CoreData 设置
  • Swift:使具有相同“形状”的两种类型符合通用协议

    我有两种不同的类型 它们代表相同的数据 并且具有完全相同的 形状 这两种不同的类型是代码生成的 我被迫处理它们 但是 我想让它们符合一个通用的协议 这样我就可以对这两种类型一视同仁 这是一个例子 假设这是我所坚持的两种代码生成类型 stru
  • 在 iOS 中,如何创建一个始终位于所有其他视图控制器之上的按钮?

    无论是否呈现模态或用户执行任何类型的转场 有没有办法让按钮在整个应用程序中 始终位于顶部 而不是屏幕顶部 有什么方法可以让这个按钮可拖动并可捕捉到屏幕上吗 我正在以苹果自己的辅助触摸作为此类按钮的示例 您可以通过创建自己的子类来做到这一点U
  • 如何将 ios7 通用应用程序升级到基于 Xcode 6 的通用故事板应用程序?

    我目前有一个基于 xcode 5 ios 7 的通用应用程序 因此有两个故事板 我正在考虑将其更新到 ios 8 有没有办法 最佳方法将两个故事板迁移到通用的单个故事板 我在 xcode 6 中看不到转换选项 None
  • PFQueryTableViewController 错误

    我正在遵循在线教程 使用 Parse 作为后端创建照片共享应用程序 我已经运行了两次教程 两次都从头开始创建应用程序 但在同一位置仍然出现相同的错误 我到处寻找解决方案 但仍然没有运气 我正在使用 PFQueryTableViewContr
  • 什么是 WKWebView 中的 WKErrorDomain 错误 4

    fatal error LPWebView encounters an error Error Domain WKErrorDomain Code 4 A JavaScript exception occurred UserInfo 0x7
  • 在 UIScrollview 上显示缩略图的最佳方法是什么(从服务器下载)

    我想在 UIScrollview 如照片应用程序 上显示许多图像 作为缩略图 所有图像将从服务器下载 据我所知 有几种选择 1 通过创建 UIImageviews 然后将它们添加为主滚动视图上的子视图 2 通过子类化一个UIView类 然后

随机推荐

  • 当进程内存不足时删除大型 Javascript 对象

    我是这种javascript的新手 所以我会给出一个简短的解释 我内置了一个网络抓取工具Nodejs收集 相当多的 数据 并用Cheerio 基本上jQuery for Node 创建一个对象然后将其上传到 mongoDB 它工作得很好 除
  • React:向现有组件添加道具

    我正在尝试找出如何使用附加道具克隆现有元素 以供参考 this mainContent
  • rtmp和rtsp协议有什么区别?

    我只是想知道 rtsp 和 rtmp 协议之间有什么区别 如果我的服务器上有 mp3 并且我正在我的 Android 中使用 http 播放它 那么它们在工作中有何不同 在android中如果我想实现rtmp或rtsp 哪个是最好的 and
  • SQL Server R2 SSRS 上的 Reporting Services 权限

    当我尝试访问 SQL Server 2008 R2 上的 SSRS 时 出现以下错误 我不确定有多少其他人已经开始使用 SQL 2008 R2 SSRS 但当我尝试访问报告服务器 url 时遇到以下错误 用户没有所需的权限 验证是否已授予足
  • Java 服务器 -- 使用 POST 发送 Push 到 google Firebase Cloud

    在我测试了推送通知与 Postman 的配合后 我想在我的应用程序中发送消息时向 FCM 发送推送请求 调用的函数将访问我的 Java 服务器并调用如下函数 POST Consumes MediaType APPLICATION JSON
  • 如何将 2 路数据绑定与模型驱动表单结合起来?

    在角度 2 中 构建形式的一种可能性是模型驱动方式 据我了解 控件失去了 2 路数据绑定 这与 ngModel 的模板驱动方式相反 将 2 路数据绑定与模型驱动表单相结合的最佳方式是什么 我尝试将模型绑定与 value 一起使用
  • 服务器重启后 Liferay 调度程序不工作

    我正在使用下面的代码安排工作 Controller RequestMapping VIEW public class MyController RenderMapping public String defaultView try Stri
  • 在 Javascript 中使用 Ruby 变量(在应用程序视图中)

    目前 我有一个可以通过名为的视图访问的 ruby 变量 json 其中包含我需要的 JSON 格式的信息 但是 我想将其传递到脚本区域 例如 有什么办法可以做到这一点吗 假设您提到的脚本标签位于 html erb 视图中 您可以使用以下命令
  • 来自 Python 子进程的实时输出/流

    我正在使用 Python 及其子进程库来使用 strace 检查调用的输出 具体如下 subprocess check output strace str processname 但是 这只能给我输出after被调用的子进程已经完成 这对我
  • 制作索引控制数组?

    C 是否有索引控制数组 我想放置一个 按钮数组 例如有 5 个按钮 它只使用一个事件处理程序来处理所有这 5 个控件的索引 就像 VB6 那样 否则我必须为这 5 个按钮中的每一个编写一个额外的事件处理程序 如果我有 100 个按钮 我需要
  • 在 Sphinx 中生成外部链接

    我想链接到 Sphinx 文档中的某个 URL a href http some url blah a 我在文档中发现了类似的内容 http sphinx doc org ext extlinks html http sphinx doc
  • 在 Swift 1.2 的 init 方法中将 self 作为参数传递

    下面的课程有一个 let 属性声明为隐式解包变量 这之前适用于 Xcode 6 2 class SubView UIView let pandGestureRecognizer UIPanGestureRecognizer required
  • 如何检查 MVC Core 配置文件中的某个部分是否存在?

    如何检查加载的 ASP NET Core 配置文件中的特定部分是否存在 我有一个 JSON 配置文件 我将其加载到其中Startup类通过ConfigurationBuilder AddJsonFile method 该 JSON 文件是一
  • 使用 ggplot 函数将 geom_path 添加到箱线图时出错

    我打算创建一个箱线图并突出显示成对比较的显着性水平 这已在一个上一篇文章 https stackoverflow com questions 14958159 indicating the statistically significant
  • 在 AddObject 之后、在 SaveChanges 之前查询对象?

    在实体框架中 是否可以在调用 SaveChanges 方法之前查询刚刚使用 添加对象 添加到上下文的对象 Thanks 要持久化一个实体 您通常将其添加到它的DbSet在上下文中 例如 var bar new Bar bar Name fo
  • Git 中的 HEAD^ 和 HEAD~ 有什么区别?

    当我在 Git 中指定祖先提交对象时 我很困惑HEAD and HEAD 两者都有一个 编号 版本 例如HEAD 3 and HEAD 2 它们对我来说看起来非常相似或相同 但是波浪号和插入符号之间有什么区别吗 经验法则 Use 大多数时候
  • 使用自定义适配器时如何获取 onItemClick(ListView) 中行的 id?

    我搜索了一段时间但找不到解决方案 情况 我正在使用一个ListView我有一个CursorSQLiteDatabase query 的结果 如果我使用一个SimpleCursorAdapter 什么时候 你打电话onItemClick Ad
  • R:重新思考数据(如何重新排列一组列中的一列?)

    我有这样的表 A B C 1 a b 1 2 a b 2 3 a b 3 4 a2 b1 1 5 a3 b2 3 例如 A 列 是一个属 例如E B 列是一个物种 E coli C 列是项目的类别 无关紧要 所以我需要了解 项目 b 由多少
  • 使用gunicorn和Flask时出现CSRF令牌错误

    我开发了一个网络应用程序 其中包含用户登录和注册的功能 我已经按照文档和教程完成了所有操作 并且 Flask 服务器一切正常 问题是 我使用gunicorn并启动一个Web服务器 打开地址 localhost 8000 在几种不同的浏览器
  • 自定义 MKAnnotation 标注视图?

    我有一个MKPointAnnotation let ann MKPointAnnotation self ann coordinate annLoc self ann title Customize me self ann subtitle