前言

了解 iOS 17 中的 MapKit 后,咱们会发现 Apple 引入了更适合 SwiftUI 的 API。

MapKit 弃用项

一旦将你的 App 方针更新到 iOS 17,Xcode 会将任何运用旧的 Map 初始化器的用法符号为已弃用:

如何使用 SwiftUI 中新地图框架 MapKit

会有正告提示:init coordinate region 已在 iOS 17 中弃用。请改用带有 MapContentBuilder 参数的地图初始化器。

在 iOS 17 中,MapKit 为 SwiftUI 引入了需要 MapContentBuilder 参数的地图初始化器。下面为大家介绍一下MapKit 相关的基础知识。

MapContentBuilder(iOS 17)

在 iOS 17 中,用于地图视图的各种初始化器都需要一个名为 MapContentBuilder 的 content 参数。MapContentBuilder 是一个结果构建器,允许在闭包中添加地图内容,例如符号、注释和自界说内容。

下面让咱们看看是怎么运用的,这里是一些伦敦地标的坐标:

extension CLLocationCoordinate2D {
  static let towerBridge = CLLocationCoordinate2D(latitude: 51.5055, longitude: -0.075406)
  static let boe = CLLocationCoordinate2D(latitude: 51.5142, longitude: -0.0885)
  static let hydepark = CLLocationCoordinate2D(latitude: 51.508611, longitude: -0.163611)
  static let kingsCross = CLLocationCoordinate2D(latitude: 51.5309, longitude: -0.1233)
}

要创建一个带有符号和注释的地图视图,详细代码如下:

struct ContentView: View {
  var body: some View {
    Map {
      Marker("Tower Bridge", coordinate: .towerBridge)
      Marker("Hyde Park", coordinate: .hydepark)
      Marker("Bank of England", 
        systemImage: "sterlingsign", coordinate: .boe)
        .tint(.green)
      Annotation("Kings Cross", 
        coordinate: .kingsCross, anchor: .bottom) {
          VStack {
              Text("在此搭乘火车!")
              Image(systemName: "train.side.front.car")
          }
          .foregroundColor(.blue)
          .padding()
          .background(in: .capsule)
      }
    }
  }
}

在没有其他选项的状况下,地图视图的鸿沟将包围地图内容。

地图交互

为了操控用户与地图的交互方式,能够传递一组允许的形式。默认状况下允许一切形式(平移、缩放、歪斜、旋转),代码如下:

Map(interactionModes: [.pan,.pitch]) { ... }

地图款式

运用 Map Style 视图修饰符能够在规范、卫星或混合款式之间切换,操控高度、显现爱好点和显现交通状况,代码如下:

Map { ...
}
.mapStyle(.hybrid(elevation: .realistic,
  pointsOfInterest: .including([.publicTransport]), 
  showsTraffic: true))

地图控件

规范的地图控件,如指南针、用户方位、歪斜、比例尺和缩放控件都实现为 SwiftUI 视图。这意味着能够将它们放置在视图的任何方位,不过需要界说一个地图范围命名空间,以将它们与它们操控的地图关联起来,代码如下:

struct ContentView: View {
  @Namespace var mapScope
  var body: some View {
    VStack {
      Map(scope: mapScope) { ... }
      MapCompass(scope: mapScope)
    }
    .mapScope(mapScope)
  }
}

要将它们放置在规范方位,运用地图控件视图修饰符,代码如下:

Map { ...
}
.mapControls {
  MapPitchToggle()
  MapUserLocationButton()
  MapCompass()
}

地图相机方位

地图相机方位界说了从地图表面上方查看地图的虚拟方位。能够运用现有的地图项、地图鸿沟、区域或用户方位来创建地图相机方位并设置初始地图方位,代码如下:

Map(initialPosition: position)

MapCameraPosition 的绑定传递给地图,使其在用户在地图上移动时盯梢相机方位,代码如下:

struct ContentView: View {
  @State private var position: MapCameraPosition = .region(.uk)
  var body: some View {
    Map(position: $position) {
      Marker("Tower Bridge", coordinate: .towerBridge)
    }
  }
}

设置方位会导致地图更改其相机方位以匹配。例如,在用户移动方位后,要在 toolbar 中添加一个按钮,以将地图重置为初始方位,代码如下:

Map(position: $position) { ...
}
.toolbar {
  ToolbarItem {
    Button("重置") {
      position = .region(.uk)
    }
  }
}

将方位设置为 .automatic 能够使地图框架内容。

总结

这就是在 iOS 17 中运用 SwiftUI 中的 MapKit 所需要了解的内容。通过引入 MapContentBuilder 和其他新的初始化器,能够更方便地创建交互式地图视图,添加符号、注释和自界说内容,并在用户移动地图相机时自动更新方位。

此外,还能够运用 Map Style 修饰符和 Map 控件来自界说地图的款式和控件。这些改进使得在 SwiftUI 中运用 MapKit 变得更加强大和灵活。