swift 如何清除在其他视图中触发的变量

rhfm7lfc  于 2023-01-29  发布在  Swift
关注(0)|答案(1)|浏览(87)

我试图清除变量值时,一个按钮被按下在另一个视图。代码如下:
根视图

struct RecipeEditorHomeMenu: View {
    @Environment(\.dismiss) var dismiss
    @State var recipeAddedSuccess = false
    @State private var showSaveButton = false
    @State var showSuccessMessage = false
    @State private var sheetMode: SheetMode = .none
    
    @ObservedObject var recipeClass = Recipe()
    var onDismiss: (() -> Void)?
   
    var body: some View {
        
        GeometryReader{ geo in
            VStack{
                if showSuccessMessage {
                    RecipeSuccessPopUp(shown: $showSuccessMessage, onDismiss: onDismiss)
                }
                RecipeEditorView(showSuccessMessage: $showSuccessMessage)
                    .blur(radius: showSuccessMessage ? 15 : 0)
                    .padding(.top, 80)
                    
               
               // Spacer()
                
                
                //display save button
                FlexibleSheet(sheetMode: $sheetMode) {
                    SaveRecipeButton(showSuccessMessage: $showSuccessMessage)
                   
                    //sets coordinates of view on dash
                 .offset(y:-200)
                }
                
            }
            .onAppear{
                recipeAddedSuccess = false
            }
            //center view
            .alignmentGuide(VerticalAlignment.center, computeValue: { $0[.bottom] })
                    .position(x: geo.size.width / 2, y: geo.size.height / 2)
            .environmentObject(recipeClass)
        }
        
    }
    
}

EditorView(我想在这里清除变量并刷新视图,这样现在它看起来是新的,并且没有变量有值了:

struct RecipeEditorView: View {
    @EnvironmentObject var recipeClass: Recipe
    @State  var recipeTitle = "" 
    @State private var recipeTime = "Cook Time"
    @State private var pickerTime: String = ""
    //calls macro pickers@State var proteinPicker: Int = 0
    @Binding var showSuccessMessage: Bool
    var cookingTime = ["5 Mins", "10 Mins","15 Mins","20 Mins","25 Mins","30 Mins ","45 Mins ","1 Hour","2 Hours", "A Long Time", "A Very Long Time"]
    var resetPickerTime: (() -> Void)?
    var body: some View {
        VStack{
            TextField("Recipe Title", text: $recipeTitle)
                .onChange(of: recipeTitle, perform: { _ in
                    recipeClass.recipeTitle = recipeTitle
                })
                .foregroundColor(Color.black)
                .font(.title3)
                .multilineTextAlignment(.center)
            //macro selectors
            HStack{
                
                Picker(selection: $carbPicker, label: Text("")) {
                   ForEach(pickerGramCounter(), id: \.self) {
                       Text(String($0) + "g Carbs")
                   }
                   .onChange(of: carbPicker, perform: { _ in
                       recipeClass.recipeCarbMacro = carbPicker
                   })
                }
                .accentColor(.gray)
               
                }
                .accentColor(.gray)
            }
            HStack(spacing: 0){
                ZStack{
                    Image(systemName:("clock"))
                        .padding(.leading, 150)
                        .foregroundColor(Color("completeGreen"))
                    Picker(selection: $pickerTime, label: Text("Gender")) {
                       ForEach(cookingTime, id: \.self) {
                           Text($0)
                       }
                    }
                    .onChange(of: pickerTime, perform: { _ in
                        recipeClass.recipePrepTime = pickerTime
                    })
                    .accentColor(.gray)
                }
                .multilineTextAlignment(.center)
            }
        }
       
    }
       
}

保存配方的按钮(并希望清除此处的变量:

struct SaveRecipeButton: View {

    @Binding var showSuccessMessage: Bool
    //stores recipe
    @EnvironmentObject var recipeClass: Recipe
   
    @State var isNewRecipeValid = false
    static var newRecipeCreated = false
    
   
    
    var body: some View {
        Button(action: {
            //action
        }){
            HStack{
                Image(systemName: "pencil").resizable()
                    .frame(width:40, height:40)
                    .foregroundColor(.white)
                
                Button(action: {
                    if (recipeClass.recipeTitle != "" &&
                        recipeClass.recipePrepTime != "" &&
                  
                    ){
                        isNewRecipeValid = true
                        showSuccessMessage = true
                        saveRecipe()
                    }
                    else{
                        showSuccessMessage = false
                        isNewRecipeValid = false
                    }
                 
                }){
                    Text("Save Recipe")
                        .font(.title)
                        .frame(width:200)
                        .foregroundColor(.white)
                }
            }
          
            .padding(EdgeInsets(top: 12, leading: 100, bottom: 12, trailing: 100))
            .background(
                RoundedRectangle(cornerRadius: 10)
                    .fill(
                        Color("completeGreen")))
            
        }
        .transition(.sideSlide)
        .animation(.easeInOut(duration: 0.25))
    }
    
     
}

我的菜谱类将每个变量作为@Published变量保存。我也尝试清除该类中的变量,但值在视图中不会刷新(例如:如果我将recipeTitle设置为“Eggs”并保存该食谱,recipeTitle不会在视图中更新)

**更新配方类:

class Recipe: ObservableObject, Identifiable {
    let id = UUID().uuidString
    @Published var recipeTitle: String = ""
    @Published var isCompleted = false
    @Published var recipeCaloriesMacro: Int = 0
    @Published var recipeFatMacro: Int = 0
    @Published var recipeProteinMacro: Int = 0
}
oxosxuxt

oxosxuxt1#

我假设你想重置Recipe中的值。因为这没有反映到RecipeEditorView中的原因是你的RecipeEditorView中的@State值。
您忽略了SwiftUI的一个基本原则:“单一真实来源”
RecipeEditorView具有多个@State值,您可以将这些值绑定到PickerTextField。然后,您可以观察它们的更改并与ViewModel Recipe同步。
不要这样做,使用ViewModel本身作为(我知道我在这里重复自己的话)“单一真实来源”
另一个问题是,如果一个视图管理一个ObservableObject的生命周期,比如示例化它并保持它,那么就将它声明为@StateObject。只有当类被注入并管理到层次结构中时,才需要@ObservedObject
RecipeEditorHomeMenu中:

@StateObject var recipeClass = Recipe()

RecipeEditorView中,删除用于定义配方的所有@State变量,例如:recipeTitlecarbPickerpickerTime,并绑定到视图模型中的值。
recipeTitle的可能实现:

// this needs to be changed
TextField("Recipe Title", text: $recipeClass.recipeTitle)

也为其他人这样做。
现在在SaveRecipeButton中,你可以将这些变量更改为你想要的任何值。重置标题将如下所示:

recipeClass.recipeTitle = ""

相关问题