首页 > 解决方案 > 使用按钮添加用户输入的数据

问题描述

好的,所以我已经为此工作了好几天了,但没有找到任何有意义的答案。我在 SwiftUI 中有一个表单,使用 @ObservedObject 从结构中提取变量。在该表单中,我有各种用户可以与之交互的文本字段和选择器。但是,我无法弄清楚如何让我的“添加”按钮将该数据实际添加到应用程序中的任何其他视图中。我按照 WWDC20 的三明治教程进行了重大更改,因此有一个带有“testData”的快速文件,基本上我正在尝试获取它,以便按钮使用用户输入来附加 testData 并显示它而不是什么。

struct Horse: Identifiable {
    var id = UUID()
    var name: String
    var gender: String
    var breed: String
    var type: String
    var scale: String
    var brand: String
    var finish: String
    var specialty: String
    
    
    var imageName: String { return name }
    var thumbnailName: String { return name + "Thumb" }
}

let testData = [
    Horse(name: "Van Gogh", gender: "Stallion", breed: "Unknown", type: "Customized", scale: "Stablemate", brand: "Peter Stone", finish: "Gloss", specialty: "OOAK")
]

所以这就是我用来建立 testData 和应该包含在其中的参数。

func addANewHorse() {
    withAnimation {
        testStore.horses.append(Horse(name: "\(horseDetails.horseName)", gender: "\(horseDetails.selectedGender.rawValue)", breed: "\(horseDetails.horseBreed)", type: "\(horseDetails.type.rawValue)", scale: "\(horseDetails.scale.rawValue)", brand: "\(horseDetails.brand.rawValue)", finish: "\(horseDetails.finish.rawValue)", specialty: "\(horseDetails.specialty.rawValue)"))
    }
}

Button("Add", action: {
    addANewHorse();
    self.presentationMode.wrappedValue.dismiss()
})

这就是我用来尝试附加 testData 以使用用户输入进行更新的方法。我知道这有点不稳定,但有人有什么建议吗?---编辑---我的主应用程序文件看起来像这样......

@main

结构 Pferd_HerdApp:应用程序 {

@StateObject private var store = HorseStore()
@StateObject private var horseDetails = HorseDetails()

var body: some Scene {
    WindowGroup {
        ContentView(store: store, horseDetails: HorseDetails())
    }
}

}

我的马店课是这样的……

class HorseStore: ObservableObject {
@Published var horses: [Horse]

init(horses: [Horse] = []) {
    self.horses = horses
}

}

让 testStore = HorseStore(马:testData)

此外,“HorseDetails”是我试图从中提取数据以附加 testData 的 observableobject,所以这里是它的代码

class HorseDetails: ObservableObject {
@Published var horseName = ""
@Published var selectedGender = Gender.allCases[0]
@Published var horseBreed = ""
@Published var purchaseDate = Date()
@Published var winCount = ""
@Published var notes = ""
@Published var brand = Brands.allCases[0]
@Published var type = Type.allCases[0]
@Published var scale = Scale.allCases[0]
@Published var finish = Finish.allCases[0]
@Published var specialRun = false
@Published var specialty = Specialty.allCases[0]

} var horseDetails = HorseDetails()

我将 testData 的 let 更改为变量

标签: swiftui

解决方案


由于您的问题遗漏了很多代码,因此我将做出一些假设。我假设您的表单(您可以在其中添加数据的按钮)和用于显示数据的视图位于两个不同的视图中。尽管在上面的代码中使用了您的视图模型 (testStore) 的一个实例,但您还没有在代码中包含您的视图模型。您需要确保在视图层次结构的根部某处创建了视图模型的实例(我假设它称为 TestStoreViewModel)并将其作为环境对象传递给您的子视图。例如,你应该这样

@main
struct YourApp: App {
    let testStoreViewModel = TestStoreViewModel()
    var body: some Scene {
        WindowGroup {
            ContentView().environmentObject(testStoreViewModel)
        }
    }
}

在您需要使用 TestStoreViewModel 中的数据的所有视图中,您应该像这样声明它

@EnvironmentObject var testStore:TestStoreViewModel

使用环境对象意味着您的可观察对象会在所有使用环境对象的视图中自动同步。上面代码中的所有其他内容都应该可以在使用 EnvironmentObjects 和单一事实来源的情况下正常工作。有关环境对象的更多信息,您可以查看这篇文章,我认为这篇文章非常适合解释 swiftui 中的环境对象。还需要注意的是,在那篇文章中,它提到了 SceneDelegte 的使用,并且 ContentView 被包裹在 UIHostingController 周围。那被我上面展示的第一段代码所取代。


推荐阅读