如何创建对象的新实例并将其传递到数组 SwiftUI

Posted

技术标签:

【中文标题】如何创建对象的新实例并将其传递到数组 SwiftUI【英文标题】:How to create new instance of object and pass it into array SwiftUI 【发布时间】:2021-04-10 19:02:54 【问题描述】:

我想创建一个简单的程序来编辑这个 JSON:https://pastebin.com/7jXyvi6Y 我创建了 Smoothie 结构并将冰沙读入数组。 现在我想创建一个新的 Smoothie 实例,我应该将它作为参数传递给 SmoothieForm。在 Smoothie 表单中,我应该用值完成字段,然后这个冰沙应该添加到数组中,并且数组应该保存在 json 中。 如何创建此 Smoothie 结构的新实例?以及如何追加到数组中?

我的冰沙有结构

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()
    

从 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#

【问题讨论】:

你弄明白了吗? 我与您的回复合作 :) 并且您的回复非常有帮助,所以感谢您的时间 :) 现在我想在 vm.smoothies.append(newSmoothie) 之后返回 listView(上一个视图)然后将所有数组保存在 json 中 :) 【参考方案1】:
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)
    

【讨论】:

以上是关于如何创建对象的新实例并将其传递到数组 SwiftUI的主要内容,如果未能解决你的问题,请参考以下文章

如何将数据从对象传递到javascript中的新数组?

如何创建 System.IO.Stream 流的实例

Firestore:如何从数组中检索数据并将其传递到表中?

JS 遍历对象数组并将值更改为匹配的键并创建一个包含对象数组 [0] 中的键的新对象

如何从选择标签传递数组对象并将值传递给 API?

如何映射一组对象,删除一个并将我的状态设置为 react-native 中的新数组?