#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オブジェクトを作成するたに使われている。



トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS