SwiftUI Tutorials
Apple公式が出しているSWiftUIのチュートリアルです!チュートリアルの手順通りにすることで、SwiftUIの学習を進めることができます!
「1章のViewの作成と結合のチュートリアル」でチュートリアルのMapView.swiftの作成が手順通りに実装できず、つまずいたので共有します!
原因としては、チュートリアルは Xcode 13.1 (iOS 15) 用に構築されており、WWDC23でSwiftUI MapKit アップデートが行われたため、古いコードでは実装できません。
MapView.swiftのコードの説明
import SwiftUI
import MapKit
struct MapView: View {
//マップの地域情報を保持するプライベート計算変数を作成
@State private var region = MKCoordinateRegion(
center: CLLocationCoordinate2D(latitude: 34.011_286, longitude: -116.166_868),
span: MKCoordinateSpan(latitudeDelta: 0.2, longitudeDelta: 0.2)
)
var body: some View {
//Map領域で初期化したカメラ位置を取るビュー
Map(coordinateRegion: $region)
}
}
struct MapView_Previews: PreviewProvider {
static var previews: some View {
MapView()
}
}
@State、$regionとは?
●@Stateとは
SwiftUIでのViewはstructであるため保持するプロパティを変更することができません。
そのため@Stateをプロパティに付与することで、プロパティはメモリ管理がSwiftUIフレームワークに委譲され、下記のようなことができるようになる。
・値の更新を監視し、値が更新されたら自動でViewをリロードする。
・struct内のプロパティを変更可能にする。
●$regionとは?
プロパティへのアクセスは宣言されたView内でのみとなる。
値が変更されるようなアクセスでは’$’を付与する必要がある。
つまり@Stateをregionプロパティに付与しており、値が変更されるようなアクセスあるため、$regionとなる。
MKCoordinateRegionとは?
MKCoordinateRegionはstructであり、特定の緯度と経度を中心とする長方形の地理的領域。
イニシャライザであるinit(center:latitudinalMeters:longitudinalMeters:)で指定された座標値と距離値から新しい座標領域を作成する。
Map(coordinateRegion: $region)とは?
イニシャライザであるinit(coordinateRegion:)で指定された座標領域$regionを使用してカメラの境界を作成。
マップを表示
下記のようにマップを表示できました。
おまけ: WWDC23を視聴し、MarkerとしてSF Symbolsを表示してみた!
import SwiftUI
import MapKit
struct Spot : Identifiable {
var id = UUID()
let latitude: Double
let longitude: Double
var coordinate: CLLocationCoordinate2D {
CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
}
}
struct MapView: View {
@State private var region = MKCoordinateRegion(
center: CLLocationCoordinate2D(latitude: 34.011_286, longitude: -116.166_868),
span: MKCoordinateSpan(latitudeDelta: 0.2, longitudeDelta: 0.2)
)
let spotList = [Spot(latitude: 34.011_286, longitude: -116.166_868)]
var body: some View {
Map(coordinateRegion: $region,
annotationItems: spotList,
annotationContent: { spot in
MapAnnotation(coordinate: spot.coordinate, content: {
ZStack {
Image(systemName: "car.fill")
.foregroundColor(.red)
}
})
})
}
}
struct MapView_Previews: PreviewProvider {
static var previews: some View {
MapView()
}
}
下記のようにspotListで指定した緯度と経度にSF Symbolsのcarを表示することができました。
参考文献