大多数浏览器和
Developer App 均支持流媒体播放。
-
认识 SwiftUI 版 MapKit
了解在功能扩展的 SwiftUI 支持下,MapKit 如何让你比以往更轻松地将 Apple 地图整合到你的 App 中。我们将向你展示如何使用 SwiftUI 向地图添加注释、覆盖层、控制项和相机等功能。
资源
相关视频
WWDC23
WWDC22
-
下载
♪ ♪
Jeff:大家好 我是 Jeff 我是 MapKit 团队的工程师 很高兴能向你介绍 适用于 SwiftUI 的 MapKit SwiftUI API 大幅扩展 借助于此 可十分便捷地在各个平台 将 Apple 地图 整合到你的 App 中 我们相信你一定会爱上 将适用于 SwiftUI 的 MapKit 用于为用户创造强大的地图体验 为了向你展示它简便的用法 我将从头开始创建 一个功能完善的旅行计划工具 本讲座全程为你讲解每一步骤 这个周末 我们一家要回新英格兰 我们打算在周六探访美丽的波士顿 上午在城市中步行观光 在充满历史气息的北区吃午餐 也许还会买个奶油卷当甜点 天气看起来也很好 所以下午我们准备去海滩 享受沙子在脚趾间的感觉 肯定会很有意思 我将创建一个 App 来帮助我们计划这一天 我将使用注解在地图上标记地点 我还将启用选择功能 这样就可以轻点每个标记 来进一步了解地点的详细信息 我也会将环顾整合进去 以便探索我们可能感兴趣的地方 我还会添加一个叠层 用于显示前往海滩的驾车路线 我会使用地图展示不同地点和区域 并增加呈现维度 启用真实海拔效果 我也会介绍如何展示卫星 和俯瞰图像 我还将为地图增加一些控件 包括用户位置按钮 这样我就能知道自己的位置 我们有很多内容要讲 现在就开始吧! 首先 我创建一个 新的 SwiftUI 项目 我要使用 MapKit 还要添加地图 不错! 我仅用一行代码 就得到了一份互动式地图! 我们一家今天先要开车进入城市 找地方停车 然后四处走走 我听说波士顿附近有一个 特别的“泊车所” 但我更喜欢去公园地下的停车场 波士顿公园风景优美 地理位置优越 正适合作为我们步行之旅的起点 我要做的第一件事是 为地图增加内容 标记出停车场的位置 我将标记放在 车辆进出停车场的斜坡正上方 位于电梯附近 我们就可以 乘坐电梯到地面并开始步行了 你将了解如何使用标记和注解 在地图的特定坐标展示内容 现在就让我们停下车 四处走走吧! 我将使用 MapContentBuilder 闭包 为地图添加一个标记 真酷! 如果你熟悉 SwiftUI 将标记添加到地图 和为列表添加视图很相似 想要查看地图是如何自动框定内容 只需通过放大地图使标记显现 那什么是标记呢? 我是否还能用内容构建器 呈现其他类型的内容呢? 标记用于在地图上的特定坐标 展示内容 类似气球的形状或许让你很眼熟 你可以在 Apple 地图 App 和各类平台中看到标记的使用 在 App Store 中 也有大量使用标记的 App 和标记类似 注解也用于在特定坐标展示内容 和标记的气球图标不同 注解展示的是 SwiftUI 视图 内容构建器也可以用于 展示叠层内容 稍后你将进一步了解更多细节 现在 你需要知道的就是 你可以使用内容构建器闭包 为地图添加各类内容 我想在停车点展示 自定义 SwiftUI 视图 就可以使用注解来进行标记 在这里 我使用 ZStack 生成一些图形和图片 这个 SwiftUI 视图将在 地图上停车场坐标的位置展示 如果你希望将视图放置在坐标上方 可以使用注解的锚参数 指定锚值为“bottom” 将使视图下边缘 位于注解的坐标上 好的! App 标出了 我们步行之旅的起点 我使用 MapContentBuilder 在地图上展示注解内容 接下来 我想让该 App 在我看地图时传达一种场所感 我将用 mapStyle 启用 真实地形海拔来实现这一点 你也将了解如何使用 mapStyle 展示卫星或俯瞰图像
你可以使用 mapStyle 修饰符设置地图风格
这是标准地图风格 默认情况下 它提供的是平面展示 就像实体纸质地图一样
看起来湖面上有一座桥 让行人可以从一侧走到另一侧 不过看懂这张平面地图 确实需要一些想象力 我将启用真实海拔地形 让地图呈现另一个视觉维度
启用真实海拔让地图变得生动起来 现在再看向湖面 我能想象自己 在夏天乘坐天鹅船泛舟湖上 也能想到船从桥下驶过的画面 使用图像地图风格是另一种 让用户获得场所感的好方法 图像地图风格展示的是 经过卫星或俯瞰图像渲染的地图 混合地图风格则 结合了图像和道路及标签 稍作回顾 我在标准 mapStyle 中 启用了真实海拔 并向你展示了如何使用 其他地图风格 接下来 我想让 App 帮助我们搜索想去的地方 在波士顿步行时 孩子们也会在我们身边 我也希望这个上午 同样让他们觉得有趣 成年人可以欣赏历史风情 而孩子们可以玩秋千、滑梯 和攀爬架! 我增加了一个搜索游乐场地的按钮 以及一个搜索海滩的按钮 App 会为每项搜索结果 添加标记 你将了解有关标记的更多细节 也可以学到该如何 将自己的 UI 覆盖到地图表面 而不对搜索结果产生遮挡 今天稍早 我创建了 一个 BeantownButtons 视图 轻点按钮即可使用 简单的查询调用搜索函数 可用于搜索游乐场地或是海滩 搜索函数使用 MKLocalSearch 寻找波士顿公园附近的停车场 并使用绑定方式写入结果
回到 App 主要的 ContentView 当中 我将添加状态来追踪搜索结果 在 BeantownButtons UI 执行搜索时 它会使用绑定方式 将结果写入此状态 我将按钮添加到地图上方 放在屏幕底部 使用 safeAreaInset 可以确保 App 的 UI 不会遮挡 地图上我添加的任何内容 或系统提供的控件 例如 Apple 地图的标志 和法律链接 接下来 我将使用内容构建器 添加搜索结果标记 我用 ForEach 为 每个搜索结果添加一个标记
我现在要试一试这些按钮 我们来找找游乐场地 看!是游乐场地! 地图已经自动缩小 将所有标记都框定在同一屏中 一眼就可以全部看到 我们来找找海滩吧 搜索结果为 MKMapItems 这是 MapKit API 例如 MKLocalSearch 用来标识地点的类型 在这里 我使用标记的地图项目初始化定式 以此方式创建的标记 使用地图项目的名称作为标题 并用地图项目包含的信息 展示代表地点的图标和色调 这些搜索结果大多显示为 浅蓝色沙滩伞标记 在处理地图项目时 标记的自动内容及风格支持 十分便捷易用 就算你不使用地图项目 也可以控制标记的展示方式 默认情况下 如你所见 气球状的标记显示地图大头针图标 你也可以提供图像资产 或系统图片作为自定义图标 你也可以使用字母组合 最多支持显示三个字母 你也可以使用色调修饰符 更换标记的颜色 稍作回顾 我刚才使用 safeAreaInset 在地图上方展示了几个按钮 并确保它们不会遮挡搜索结果标记 接下来 我将让 App 控制地图显示的内容 我一直在向地图添加内容 每次添加时 地图就会 自动将内容框定在同一屏中 我将展示如何在需要时 启用该便捷动作 我也将展示如何完整展现某一区域 比如波士顿地区北部海岸的海岸线 现在 我们看到的是海滩
如果我移到其他位置 并搜索游乐场地 地图不再自动展示 波士顿公园停车点附近的结果 要在用户与地图互动后 展示搜索结果 我需要重新设置 地图的相机位置状态 让地图将标记框定在一屏中…
现在 我将添加状态来追踪位置 我选择默认的自动定位 它会将我们添加到 地图上的内容框定于同一屏
然后将此绑定传递给 地图的初始化定式
我使用 onChange 修饰符 来确认搜索结果何时更新 更新之后 我只需要将相机位置改回自动 确保搜索到的结果可见
我们来试试看 搜索海滩 看到结果 然后在搜索游乐场地前 移动到其他地方
好极了! 现在我执行搜索时 即使一路移到罗德岛 搜索结果也会全部展示出来 我还想用位置状态来实现一项功能 在波士顿度过愉快的上午之后 我们一家驱车向北 打算在海滩上度过下午 我希望 App 可以简便地 显示出整个北部海岸线 让我们对要去的目的地 有个大概的印象 我将用位置状态来实现
首先添加城市和北部海岸的 坐标区域 我要切换到 BeantownButtons UI 并为我们的位置状态添加绑定
我还要添加两个按钮 分别将相机位置指向一个区域
轻点“City”按钮时 地图就会显示波士顿 轻点“Waves”按钮时 地图则会显示整个北部海岸线
现在我切回 ContentView 并将位置绑定传递给按钮 UI
我们来试试看! 轻点“Waves”按钮时 地图的位置更新 显示北部海岸区域 轻点“City”按钮时 地图再次更新 显示波士顿 在幕后 地图显示的区域 都是由 MapCamera 控制的 相机从某个高度对准地面上的坐标 它的朝向决定了地图哪些部分可见 我正在构建的 App 并没有创建或配置相机本身 它只是通过 MapCameraPosition 简单地指定了视图中可见的部分 MapKit 负责替我调整相机 App 使用 automatic 相机位置 来框定内容 例如搜索结果 它使用 region 位置 来显示波士顿和北部海岸 你也可以指定相机位置 来框定其他内容 Rect 位置用来显示某个地区 和我们使用 region 的方式一样 它只是在地图上用矩形表示该地区 而不是根据坐标区域表示 我们来细看一下 item、camera 和 userLocation 相机位置 使用 MKMapItem 你可以展示某个特定地点 它对所有类型的地图项目都生效 如果你的地图项目代表科德角湾 MapKit 会自动 将地图缩小 使之适应屏幕 如果你想展示北区的某个公园 相机会将地图放大 显示周边环境 并让你拥有一种场所感 你也可以提供 根据需求配置的 MapCamera 使用带俯仰角的 MapCamera 是呈现 3D 视角的好方法 或许你会希望相机能跟随用户的脚步 一起沿着查尔斯河移动 你还可以提供后备位置 它将在用户位置未知时使用 例如定位权限没有开启 或是设备正处在定位中时 如果你为相机位置状态提供了绑定 MapKit 将在 相机位置变化时进行更新 这是用户所在地相机位置 followsUserLocation 属性为真 如果用户将该画面移开 相机不再跟随用户的位置 当用户与地图互动时 相机位置状态为 positionedByUser 如果 App 将相机位置状态 重新设置为 userLocation 相机将跟随用户的位置 由你的 App 设置相机位置状态时 不再使用 positionedByUser 无论指定的是哪种相机位置类型 用户都可以通过 与地图互动来变换相机视角 好的!现在 App 可以 掌控地图上呈现的内容了 我刚才使用 automatic 相机位置 确保搜索结果 在用户与地图互动后依然可见 我用 region 相机位置 来展示波士顿和北部海岸 接下来 我不想只 搜索波士顿公园周边 而是希望地图移动到 我有兴趣拜访的地区 并在那里进行搜索 我将向你展示 如何在相机变动时获取可见区域 我将新增状态来追踪 地图上的可见区域 添加 onMapCameraChange 修饰符 我将在更新语境中获取可见区域 并将其存入我自己的状态中 默认情况下 提供给 onMapCameraChange 的闭包 将在用户 完成与地图的互动时被调用 如要在用户与地图互动时调用闭包 你可以通过传递频率参数 来请求连续更新 除了我在这里使用的 region 属性 语境中也有可见地图矩形 和地图相机本身的属性 根据不同需求 我也可以使用它们 我准备更新 BeantownButtons 让它在用户可见的区域内进行搜索 我将 visibleRegion 添加到按钮
并在搜索请求中使用 在 ContentView 中 我将 visibleRegion 传递给按钮 UI
让我们来搜索北部海岸的沙滩! 北部海岸在这里 显示一些沙滩吧! 很好!那可以找出罗德岛吗?
真棒!现在我也可以搜索 罗德岛的沙滩了! 我通过 onMapCameraChange 启用了这个功能 它会在可见范围内出现变更时 告知我们 接下来 我希望该 App 能让 去哪个海滩的选择变得更简单 可选项非常多 首先 我将为搜索结果的选取 添加支持 现在 如果我轻点搜索结果标记 什么都不会发生 没有选中状态 所以标记不可选
要启用选择 我只需要为地图添加选择绑定
现在我们来看看 轻点结果时会发生什么
气球标记通过动画显示它被选中了! 我使用 MKMapItem 作为选择类型 使每个代表地图项目的标记 都已可选 停车点注解并不代表地图项目 因此它不可选 如你想支持对标识类型不一定相同的 标记和注解进行选中 打上标签即可 这和使用选择器和列表 管理选择功能原理相同 此处 selectedTag 的状态是 Int 每个标记都打上了 Int 标签 于是绑定就为两者启用了选择功能 在使用标签来启用选择功能时 你可以为选择状态 使用任何符合可哈希的类型 稍作回顾 我刚才向地图 添加了 MKMapItem 选择绑定 为搜索结果标记启用选择功能 接下来 App 应该可以展示 关于所选搜索结果的更多信息 我将添加环顾预览 对海滩的风景先睹为快 同时我也会添加海滩的名称 和行车所需时间 今天早些时候 在写 BeantownButtons 视图时 我也顺便写了 一个 ItemInfoView 用来展示标题、预计旅行时间 和环顾预览 环顾预览 可以让我看到所选海滩的风景 该预览展示了环顾场景 你可以使用 MKLookAroundSceneRequest 获取给定地图项目的场景 在视图展示时 此场景将被抓取 同样 所选搜索结果 出现变更时也将进行抓取 最后 有一种属性使用 DateComponentsFormatter 来格式化 MKRoute 的预计旅行时间 以供显示 我现在切换回 ContentView 并添加此 ItemInfoView 先说重要的: 我要获取从停车场 到所选搜索结果的路线 我先添加状态来追踪路线 然后添加使用 MKDirections 的函数进行获取 最后设置状态
我要添加另一个 onChange 修饰符 以便在选项更改时调用函数
App 会在选中搜索结果时 显示项目信息视图
同时 我将隐藏搜索结果的标记标题 让地图的显示更加清晰 ItemInfoView 则会 展示所选地点的名称 好了!让我们看看效果如何
我听说这附近有片游乐场地
它看起来很不错
我想知道这边有什么
太棒了! 这里就有附带游乐场的海滩? 对我们家来说 这个选择再好不过了 从波士顿公园出发大约需要半小时 看起来是个好地方 稍作回顾 我添加了环顾视图 它将在标记被选中时进行展示 它可以和 MKRoute 生成的预计旅行时间 共同帮助我们选择去哪个海滩 接下来 因为我们已经 有了展示旅行时间的路线 我们完全可以用它来展示 从波士顿公园到所选搜索结果的 行车路线 我将添加 MapPolyline 叠层 来显示路线 并向你介绍其他几种 可添加的叠层内容 在路线可用时 我添加 MapPolyline 并使用蓝色显示 让我们在地图上看一看
这条路看上去不错! 配合 MKRoute 使用 MapPolyline 非常简单 你也可以使用 MapPolyline 来展示自己的位置数据 你可以使用 StrokeStyle 实现一些丰富的视觉效果 例如虚线和渐变 如果你想突出显示某片区域 可以试试 MapPolygon 或者 MapCircle 这里就是用两个多边形 标记了两个公园 这是用两个圆圈 标记上述公园的效果 你可以看到 每个圆圈都指定了叠层级别 粉红色的圆圈使用 道路上方默认叠层级别 地图的标签就会出现在圆圈之上 蓝绿色的圆圈使用的则是标签上方 App 已经逐渐成形了 我添加了 MapPolyline 来展示前往海滩的行车路线 并向你介绍了 其他几种可用的叠层类型 接下来 我想让 App 轻松确定我的所在地 我们到达波士顿 开始四处闲逛时 有可能 甚至有很大可能会出现迷路的情况 我将添加 UserAnnotation 为内容来展示我的所在地 并添加 MapUserLocationButton 来找到我自己 你也可以了解其他几种 可供使用的地图控件 当我试图找到自己的时候 通常会先寻找地图上的蓝色小圆点 我向地图内容添加了 UserAnnotation 现在我的位置就出现在地图上 我在哪里呢? 在那里! 看起来我离刚才查看的 游乐场地和海滩还远得很呢
我得把地图缩小 一直移动 才能到达 Apple Park MapUserLocationButton 会让此过程更加简便
现在我可以轻点按钮 来显示自己的位置 地图相机会跟随我的脚步四处移动 我也添加了 MapCompass 和 MapScaleView
默认的 mapControls 配置 会在地图发生旋转时显示指南针 并在用户放大缩小地图时 显示比例尺 我也希望该 App 能拥有这些默认控件 所以在用户位置按钮上进行了指定 所有这些都使用 mapControls 修饰符进行添加 这样地图就会自动 在默认位置显示它们 这包括所有平台上的地图控件 其中就有 macOS 上的 MapZoomStepper 和 MapPitchSlider 如果你想自由安放这些控件 可以使用你自己的 UI 进行呈现 地图控件只是视图 因此无需使用 mapControls 修饰符 只需像其他视图一样进行添加即可 在操作时 你将使用 mapScope 修饰符 来关联控件和特定地图范围 讲座已经接近尾声 让我们来总结一下今天介绍的内容 适用于 SwiftUI 的 MapKit 是一种十分强大、 操作简单的 API 用于将 Apple 地图整合进你的 App 你可以使用标记、 注解和叠层在地图上展示你的内容 地图相机和地图控件 让你可以根据需求自定义地图 最后 MapStyle 和环顾 为用户提供真实的场所感 这些只是适用于 SwiftUI 的 MapKit 的几项功能 请你务必查看开发者文件 以进一步了解更多信息 当然 因为一切都基于 SwiftUI 你的地图将在所有平台上表现出色 总结到这里 还有以下几点想与你分享 我们已将 Apple Maps Server API 进行拓展 以支持 Autocomplete 和 Directions 如想进一步了解 如何使用 Server API 请查看去年的 WWDC 讲座 “认识 Apple Maps Server API” 我们也一如既往期待你的反馈! 请使用反馈助理 来告诉我们你的想法 最后很重要的一点是 我希望你能去查看一下 今年 SwiftUI 推出的新功能 动画方案是为 你的地图添加动画的好方法! 请查看以下讲座 就讲到这里啦!非常感谢你的观看! 我们海滩见! ♪ ♪
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。