问题描述
我是一个新手,正在开发一个应用程序,该应用程序基本上有一个包含食物的冰箱类。我正在尝试拥有一个带有食物清单的冰箱。所以我将 foodList 设置为一个已发布的对象,并在程序启动时实例化一个 @StateObject 冰箱。基本上,从我的角度来看,每当 foodList 发生变化时,冰箱对象都会保存它的状态并给我一个新的视图。
此外,我想将此@StateObject 冰箱传递给另一个视图,以便我的另一个视图可以修改冰箱中的 foodList
下面是我的代码
struct ContentView: View {
@StateObject private var fridge=Fridge();
private var dbStartWith=0;
@State private var selection = 1;
@State private var addFood = false;
var body: some View {
TabView(selection: $selection) {
NavigationView {
List(fridge.container!){
food in NavigationLink(destination: FoodView()) {
Text("HI")
}
}.navigationBarTitle(Text("Fridge Items"),displayMode: .inline)
.navigationBarItems(trailing:
NavigationLink(destination: AddFoodView(fridgeView: fridge)) {
Image(systemName: "plus.circle").resizable().frame(width: 22,height: 22)
} )
}
.tabItem {
Image(systemName: "house.fill")
Text("Home")
}
.tag(1)
Text("random tab")
.font(.system(size: 30,weight: .bold,design: .rounded))
.tabItem {
Image(systemName: "bookmark.circle.fill")
Text("profile")
}
.tag(0)
}
}
}
struct FoodView: View{
var body: some View{
NavigationView{
Text("food destination view ");
}
}
}
struct AddFoodView: View{
@Observedobject var fridgeView: Fridge;
@State private var name = ""
@State private var count : String = "1"
@State private var category : String = "肉类";
@State var showCategory = false
@State var showCount = false
var body: some View{
ZStack{
NavigationView{
Form{
HStack{
Text("食品")
TextField("请输入材料名",text: $name);
}.padding(.bottom,10).padding(.top,10).padding(.leading,10).padding(.trailing,10)
HStack{
Text("数量")
TextField("请选择数量",text:$count,onEditingChanged:{(changed) in
self.hideKeyboard();
self.showCount=changed;
}){}
}.padding(.bottom,10)
HStack{
Text("种类")
TextField("请选择种类",text: $category,onEditingChanged:{(changed) in
self.hideKeyboard();
self.showCategory=changed;
}){}
}.padding(.bottom,10)
}
}.navigationBarItems(trailing: NavigationLink(destination: FoodView()){
Text("保存").foregroundColor(Color.blue).font(.system(size: 18,design: .default))
}).simultaneousGesture(TapGesture().onEnded{
var tempFood=Food(id: fridgeView);//not completed yet
})
ZStack{
if self.showCount{
Rectangle().fill(Color.gray)
.opacity(0.5)
vstack(){
Spacer(minLength: 0);
HStack{
Spacer()
Button(action: {
self.showCount=false;
},label: {
Text("Done")
}).frame(alignment: .trailing).offset(x:-15,y:15)
}
Picker(selection: $count,label: EmptyView()) {
ForEach(1..<100){ number in
Text("\(number)").tag("\(number)")
}
}.labelsHidden()
} .frame(minWidth: 300,idealWidth: 300,maxWidth: 300,minHeight: 250,idealHeight: 100,maxHeight: 250,alignment: .top).fixedSize(horizontal: true,vertical: true)
.background(RoundedRectangle(cornerRadius: 27).fill(Color.white.opacity(1)))
.overlay(RoundedRectangle(cornerRadius: 27).stroke(Color.black,linewidth: 1))
.offset(x:10,y:-10)
Spacer()
}
if self.showCategory{
let categoryArr = ["肉类","蔬菜类","饮料类","调味品类"]
ZStack{
Rectangle().fill(Color.gray)
.opacity(0.5)
vstack(){
Spacer(minLength: 0);
HStack{
Spacer()
Button(action: {
self.showCategory=false;
},label: {
Text("Done")
}).frame(alignment: .trailing).offset(x:-15,y:15)
}
Picker(selection: $category,label: EmptyView()) {
ForEach(0..<categoryArr.count){ number in
Text(categoryArr[number]).tag(categoryArr[number])
}
}.labelsHidden()
} .frame(minWidth: 300,vertical: true)
.background(RoundedRectangle(cornerRadius: 27).fill(Color.white.opacity(1)))
.overlay(RoundedRectangle(cornerRadius: 27).stroke(Color.black,linewidth: 1))
Spacer()
}.offset(x:10,y:20)
}
}
}.animation(.easeInOut)
}
}
基本上我想将 @StateObject private var fridge
传递给 struct AddFoodView: View
,以便我的 AddFoodView
可以使用该变量。根据我在网上学到的,我认为我需要像这样 @Observedobjects
注入 NavigationLink(destination: AddFoodView(fridgeView: fridge))
。这不会给我带来让我困惑的错误(至少在调试器阶段)。 fridge
不是 Food
变量,fridgeView
不是 @Observedobject Food
变量吗?
如果我做这样的事情AddFoodView(fridgeView: $fridge))
。有错误说 Cannot convert value '$fridge' of type 'Observedobject<Fridge>.Wrapper' to expected type 'Fridge',use wrapped value instead
解决方法
@StateObject
和 @ObservedObject
是事实来源,它们彼此非常相似,几乎可以互换。
要与其他 View
共享这些,您应该使用 AddFoodView
将其传递给 .environmentObject(fridge)
并将 @ObservedObject var fridgeView: Fridge;
中的 AddFoodView
更改为 {{1} }.
在 "Managing Model Data in Your App" 上查找 Apple 文档。
@EnvironmentObject var fridgeView: Fridge
另一个很好的来源是 Apple SwiftUI 教程,尤其是 "Handling User Input"