SwiftUIでListを実装し設計を学ぶ①
こんにちは。2児ママさんエンジニアのトモヨです。
前回の記事で簡単なList実装を行いましたが、1つのクラスでささっと書いてしまう実装でした。現実のアプリ作成ではデータが複雑であるため、クラス分岐は必須であり、データとViewは分割すべきです。
今回はViewとデータを分割し、管理をApp(一番上の親View)で行う方法を書きたいと思います。
実際に記載したコードはこちらです
果物のリストを一覧にする、そしてタップすると詳細が表示される一般的なListです。
まずはデータをjson形式で記載します。
[
{
"name": "strawberry",
"id": 1001,
"color": "red",
"imageName": "strawberry"
},
{
"name": "banana",
"id": 1002,
"color": "yellow",
"imageName": "banana"
},
{
"name": "lemon",
"id": 1003,
"color": "yellow",
"imageName": "lemon"
},
{
"name": "orange",
"id": 1004,
"color": "orange",
"imageName": "orange"
}
]
jsonではデータを扱いづらいのでstruct(構造体)で扱えるようにしたいです。
なのでfruitsData.swiftというstructを作成しました。
struct FruitsData: Hashable, Codable, Identifiable {
var id: Int
var name: String
var color: String
private var imageName: String
var image: Image {
Image(imageName)
}
}
データを読み込むクラスとしてModelData.swiftを作成します
import Foundation
import Combine
// 今は変数として定義していますが、最終的にclassとして定義します。
var fruits: [FruitsData] = load("fruitsData.json")
func load<T: Decodable>(_ filename: String) -> T {
let data: Data
guard let file = Bundle.main.url(forResource: filename, withExtension: nil)
else {
fatalError("Couldn't find \(filename) in main bundle.")
}
do {
data = try Data(contentsOf: file)
} catch {
fatalError("Couldn't load \(filename) from main bundle:\n\(error)")
}
do {
let decoder = JSONDecoder()
return try decoder.decode(T.self, from: data)
} catch {
fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)")
}
}
Listから読み込みます
import SwiftUI
struct FruitsList: View {
var body: some View {
List(fruits) { fruits in
Text(fruits.name)
}
}
}
struct FruitsList_Previews: PreviewProvider {
static var previews: some View {
FruitsList()
}
}
ひとまず、データを取得しListに表示するということは出来ました。
さらに複雑なセルを作成するため、続きは次回記載します。
この記事が気に入ったらサポートをしてみませんか?