- 追加された行はこの色です。
- 削除された行はこの色です。
#author("2022-07-21T07:24:41+00:00","default:src128","src128")
#author("2022-07-21T08:01:35+00:00","default:src128","src128")
&tag(SwiftUI/日本語チュートリアル2);
*目次 [#o4046361]
#contents
*関連ページ [#v37374c7]
*参考情報 [#de50f83f]
-[[【第2回】日本語版SwiftUIチュートリアル【リストとナビゲーション】 | HIRO LAB BLOG:https://hirlab.net/nblog/category/programming/art_1440/]]
*第2回:リストとナビゲーション ~動的なビュー生成~ [#he2a741d]
** Step 1. モデルを作る [#cde9f629]
-Modelsディレクトリを作成。
-そのなかにLandmark.swiftを作る。
#pre{{
import SwiftUI
struct Landmark: Hashable, Codable{
var id: Int
var name: String
fileprivate var imageName: String
fileprivate var coordinates: Coordinates
var state: String
var park: String
var category: Category
var locationCoordinate: CLLocationCoordinate2D {
CLLocationCoordinate2D(
latitude: coordinates.latitude,
longitude: coordinates.longitude)
}
enum Category: String, CaseIterable, Hashable, Codable{{
case featured = "Featured"
case lakes = "Lakes"
case rivers = "Rivers"
case mountains= "Mountains"
}
}
extension Landmark {
var image: Image {
ImageStore.shared.image(name: imageName)
}
}
struct Coordinates: Hashable, Codable {
var latitude: Double
var longitude: Double
}
}}
** Step 2. データ処理部 [#ub7fa690]
-ModelsディレクトリにData.swiftを作成。内容は以下。
#pre{{
import UIKit
import SwiftUI
import CoreLocation
let landmarkData: [Landmark] = load("landmarkData.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)")
}
}
final class ImageStore {
typealias _ImageDictionary = [String: CGImage]
fileprivate var images: _ImageDictionary = [:]
fileprivate static var scale = 2
static var shared = ImageStore()
func image(name: String) -> Image {
let index = _guaranteeImage(name: name)
return Image(images.values[index], scale: CGFloat(ImageStore.scale), label: Text(name))
}
static func loadImage(name: String) -> CGImage {
guard
let url = Bundle.main.url(forResource: name, withExtension: "jpg"),
let imageSource = CGImageSourceCreateWithURL(url as NSURL, nil),
let image = CGImageSourceCreateImageAtIndex(imageSource, 0, nil)
else {
fatalError("Couldn't load image \(name).jpg from main bundle.")
}
return image
}
fileprivate func _guaranteeImage(name: String) -> _ImageDictionary.Index {
if let index = images.index(forKey: name) { return index }
images[name] = ImageStore.loadImage(name: name)
return images.index(forKey: name)!
}
}
}}
-要はjsonからLandmarkオブジェクトを作成するたに使われている。