如何使用 SwiftUI 中新地圖框架 MapKit
前言
了解 iOS 17 中的 MapKit 后,我們會發現 Apple 引入了更適合 SwiftUI 的 API。
MapKit 棄用項
一旦將你的 App 目標更新到 iOS 17,Xcode 會將任何使用舊的 Map 初始化器的用法標記為已棄用:
會有警告提示: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 變得更加強大和靈活。