簡體   English   中英

如何創建 object 的新實例並將其傳遞到數組 SwiftUI

[英]How to create new instance of object and pass it into array SwiftUI

我想創建一個簡單的程序來編輯這個 JSON: https://pastebin.com/7jXyvi6Y我創建了 Smoothie 結構並將冰沙讀入數組。 現在我想創建一個新的 Smoothie 實例,我應該將它作為參數傳遞給 SmoothieForm。 在冰沙形式中,我應該用值填寫字段,然后將此冰沙添加到數組中,並且數組應保存在 json 中。 如何創建此 Smoothie 結構的新實例? 而append怎么成數組呢?

我的冰沙有結構

import Foundation
import SwiftUI

struct Smoothie : Hashable, Codable, Identifiable {
    var id: Int
    var name: String
    var category: Category
    var wasDone: Bool
    var isFavorite: Bool
    var time: String
    var ingedients: [Ingedients]
    var steps: [Steps]
    var image : Image {
        Image(imageName)
    }
    
    enum Category: String, CaseIterable, Codable {
        case forest = "Forest fruit"
        case garden = "Garden fruit"
        case egzotic = "Exotic"
        case vegatble = "Vegetables"
    }
    
    private var imageName: String
    struct Steps: Hashable, Codable {
        var id: Int
        var description: String
    }
    struct Ingedients: Hashable, Codable {
        var id: Int
        var name: String
        var quantity: Double
        var unit: String
    }
}

現在我用前幾個字段構建了表單視圖:

struct SmoothieForm: View {
    
   
    var body: some View {
        VStack {
        Text("Add smooth")
            HStack {
                Text("Name")
                TextField("Placeholder", text: .constant(""))
            }
            HStack {
                Text("Category")
                TextField("Placeholder", text: .constant(""))
            }
            HStack {
                Text("Time")
                TextField("Placeholder", text: .constant(""))
            }
            Divider()
            
        }
        .padding(.all)
    }
}

struct SmoothieForm_Previews: PreviewProvider {
    static var previews: some View {
        SmoothieForm()
    }
}

Class 用於從 json 加載數據:

import Foundation

final class ModelData:ObservableObject{
    @Published var smoothies: [Smoothie] = load("smoothieData.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)")
    }
    
}

我每天使用 c #

import SwiftUI
//You need default values so you can initialize an empyty item
struct Smoothie : Hashable, Codable, Identifiable {
    //Find a way to make this unique maybe switch to UUID
    var id: Int = 999999
    var name: String = ""
    var category: Category = Category.unknown
    var wasDone: Bool = false
    var isFavorite: Bool = false
    var time: String = ""
    var ingedients: [Ingedients] = []
    var steps: [Steps] = []
    var image : Image {
        if !imageName.isEmpty{
            return Image(imageName)
        }else{
            return Image(systemName: "photo")
        }
    }
    
    enum Category: String, CaseIterable, Codable {
        case forest = "Forest fruit"
        case garden = "Garden fruit"
        case egzotic = "Exotic"
        case vegatble = "Vegetables"
        case unknown
    }
    
    private var imageName: String = ""
    struct Steps: Hashable, Codable {
        var id: Int
        var description: String
    }
    struct Ingedients: Hashable, Codable {
        var id: Int
        var name: String
        var quantity: Double
        var unit: String
    }
}
struct SmothieForm: View {
    //Give the View access to the Array
    @StateObject var vm: ModelData = ModelData()
    //Your new smoothie will be an empty item
    @State var newSmoothie: Smoothie = Smoothie()
    var body: some View {
        VStack {
            Text("Add smooth")
            HStack {
                Text("Name")
                //reference the new smoothie .constant should only be used in Preview Mode
                TextField("Placeholder", text: $newSmoothie.name)
            }
            VStack {
                Text("Category")
                //reference the new smoothie .constant should only be used in Preview Mode
                Picker(selection: $newSmoothie.category, label: Text("Category"), content: {
                    ForEach(Smoothie.Category.allCases, id: \.self){ category in
                        Text(category.rawValue).tag(category)
                    }
                })
            }
            HStack {
                Text("Time")
                //reference the new smoothie .constant should only be used in Preview Mode
                TextField("Placeholder", text: $newSmoothie.time)
            }
            Divider()
            //Append to array when the user Saves
            Button("Save - \(vm.smoothies.count)", action: {
                vm.smoothies.append(newSmoothie)
            })
        }
        .padding(.all)
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM