8
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SwiftUIAdvent Calendar 2023

Day 1

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

Last updated at Posted at 2023-11-01

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:)で指定された座標値と距離値から新しい座標領域を作成する。

Map(coordinateRegion: $region)とは?

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

マップを表示

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

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

参考文献

8
4
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?