[Swift]SwiftUIチュートリアル Section5に入門してみた。[Building Lists and Navigation編]

Swift

はじめに

前回からの続きでSwiftUIのチュートリアル入門になります。

もと記事サイト

Building lists and navigation | Apple Developer Documentation
With the basic landmark detail view set up, you need to provide a way for users to see the full list of landmarks, and t...

Step0

このセクションでは、前回までに作成したLandmarkListを動的にリスト表示できるようにします。

Step1

List内で固定配置していたLandmarkRowを削除し、Listのイニシャライザにlandmarks配列を渡します。
Listのイニシャライザには2つの方法があり、まず最初に紹介するのは、Landmarkで設定されているidをパラメータとして渡す方法です。

import SwiftUI

struct LandmarkList: View {
    var body: some View {
        List(landmarks, id: \.id) { landmark in
            
        }
    }
}

struct LandmarkList_Previews: PreviewProvider {
    static var previews: some View {
        LandmarkList()
    }
}

Step2

Listのクロージャ内でLrandmarkRowを生成します。
これでLandmarksの中身が表示されます。

import SwiftUI

struct LandmarkList: View {
    var body: some View {
        List(landmarks, id: \.id) { landmark in
            LandmarkRow(landmark: landmark)
        }
    }
}

struct LandmarkList_Previews: PreviewProvider {
    static var previews: some View {
        LandmarkList()
    }
}

余談ですが、一意で設定するのはselfでもいいようです。
ただこの場合、LandmarkHashableが付いていないとエラーになります。

import SwiftUI

struct LandmarkList: View {
    var body: some View {
        List(landmarks, id: \.self) { landmark in
            LandmarkRow(landmark: landmark)
        }
    }
}

struct LandmarkList_Previews: PreviewProvider {
    static var previews: some View {
        LandmarkList()
    }
}

Step3

次にLandmark自体をIdentifiableを準拠さ、一意となるプロパティを設定する方法です。
Landmarkには既に一意となるidプロパティが設定されているので、ここではIdentifiableを宣言するだけになります。

import Foundation
import SwiftUI
import CoreLocation

struct Landmark: Hashable, Codable, Identifiable {
    var id: Int
    var name: String
    var park: String
    var state: String
    var description: String
    
    private var imageName: String
    var image: Image {
        Image(imageName)
    }
    
    private var coordinates: Coordinates
    var locationCoordinate: CLLocationCoordinate2D {
        CLLocationCoordinate2D(
            latitude: coordinates.latitude,
            longitude: coordinates.longitude)
    }

    struct Coordinates: Hashable, Codable {
        var latitude: Double
        var longitude: Double
    }
}

Step4

あとは、LandmarkListのイニシャライザを変更します。
先程は、要素の一意となるプロパティを宣言する必要がありましたが、こちらは既にIdentifiableでidが一意であることが保証されているのでLandmarksをパラメータに設定するだけになりました。

import SwiftUI

struct LandmarkList: View {
    var body: some View {
        List(landmarks) { landmark in
            LandmarkRow(landmark: landmark)
        }
    }
}

struct LandmarkList_Previews: PreviewProvider {
    static var previews: some View {
        LandmarkList()
    }
}

まとめ

これでコレクション内にあるデータを動的にリスト表示することができるようになりました。
Listのイニシャライザに関してはちょっと戸惑うところもあるかもしれませんが、リスト表示する際には基本的に一意性が担保されていることが多いかと思うので慣れれば問題ないかなと思います。

コメント

タイトルとURLをコピーしました