SwiftUI Tutorials①: Creating and combining viewsでSwiftUIを初めてみよう！〜MapKit〜

## SwiftUI Tutorials
Apple公式が出しているSWiftUIのチュートリアルです！チュートリアルの手順通りにすることで、SwiftUIの学習を進めることができます！
「1章のViewの作成と結合のチュートリアル」でチュートリアルのMapView.swiftの作成が手順通りに実装できず、つまずいたので共有します！
原因としては、チュートリアルは Xcode 13.1 (iOS 15) 用に構築されており、WWDC23でSwiftUI MapKit アップデートが行われたため、古いコードでは実装できません。
## MapView.swiftのコードの説明
```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:)で指定された座標値と距離値から新しい座標領域を作成する。

https://developer.apple.com/documentation/mapkit/mkcoordinateregion

### Map(coordinateRegion: $region)とは？
イニシャライザであるinit(coordinateRegion:)で指定された座標領域$regionを使用してカメラの境界を作成。

https://developer.apple.com/documentation/mapkit/mkmapview/cameraboundary/3141909-init/

## マップを表示
下記のようにマップを表示できました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090887/2cfd6654-7b3e-8408-be9c-989ae363044a.jpeg" width=300>

## おまけ：　WWDC23を視聴し、MarkerとしてSF Symbolsを表示してみた！
```MapView.swift

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を表示することができました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090887/9344b71d-81da-d00e-535a-90ad1be30a4d.jpeg" width=300>

https://developer.apple.com/documentation/mapkit/marker

## 参考文献

https://developer.apple.com/tutorials/swiftui/creating-and-combining-views

https://developer.apple.com/forums/thread/732722

https://www.isoroot.jp/blog/2381/

https://developer.apple.com/videos/play/wwdc2023/10043/

https://ios-docs.dev/swiftui-mapkit/