You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI中如何在另一个视图触发时清除变量?

问题原因

你的视图里用了独立的@State变量(比如recipeTitle、pickerTime),这些变量只会在自身变化时同步到Recipe类,但反过来,当Recipe类的@Published属性被清空时,不会同步回这些@State变量,导致视图还显示旧值。


解决方案

1. 让视图直接绑定到Recipe的@Published属性

删掉RecipeEditorView里的@State变量,直接用@EnvironmentObject的recipeClass属性做双向绑定,这样视图和数据模型会实时同步。

修改后的RecipeEditorView代码:

struct RecipeEditorView: View {
    @EnvironmentObject var recipeClass: Recipe
    @Binding var showSuccessMessage: Bool
    
    let 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 body: some View {
        VStack{
            // 直接绑定到recipeClass的属性,不用单独@State
            TextField("Recipe Title", text: $recipeClass.recipeTitle)
                .foregroundColor(.black)
                .font(.title3)
                .multilineTextAlignment(.center)
            
            // 碳水选择器直接绑定到recipeClass的对应属性
            HStack{
                Picker(selection: $recipeClass.recipeCarbMacro, label: Text("")) {
                    ForEach(pickerGramCounter(), id: \.self) {
                        Text(String($0) + "g Carbs")
                    }
                }
                .accentColor(.gray)
            }
            
            HStack(spacing: 0){
                ZStack{
                    Image(systemName: "clock")
                        .padding(.leading, 150)
                        .foregroundColor(Color("completeGreen"))
                    // 烹饪时间选择器直接绑定到recipeClass的属性
                    Picker(selection: $recipeClass.recipePrepTime, label: Text("")) {
                        ForEach(cookingTime, id: \.self) {
                            Text($0)
                        }
                    }
                    .accentColor(.gray)
                }
                .multilineTextAlignment(.center)
            }
        }
    }
    
    // 补充你原来的pickerGramCounter方法示例
    private func pickerGramCounter() -> [Int] {
        return Array(0...100)
    }
}

2. 在保存按钮里添加清空逻辑

在SaveRecipeButton的保存方法执行完后,清空recipeClass的所有属性,因为视图已经绑定到@Published属性,清空后视图会自动刷新成初始状态。

修改后的SaveRecipeButton代码:

struct SaveRecipeButton: View {
    @Binding var showSuccessMessage: Bool
    @EnvironmentObject var recipeClass: Recipe
    
    @State var isNewRecipeValid = false
    
    var body: some View {
        Button(action: {}){
            HStack{
                Image(systemName: "pencil").resizable()
                    .frame(width:40, height:40)
                    .foregroundColor(.white)
                
                Button(action: {
                    guard !recipeClass.recipeTitle.isEmpty, !recipeClass.recipePrepTime.isEmpty else {
                        showSuccessMessage = false
                        isNewRecipeValid = false
                        return
                    }
                    
                    isNewRecipeValid = true
                    showSuccessMessage = true
                    saveRecipe()
                    // 保存完成后清空Recipe的所有属性
                    resetRecipe()
                }){
                    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))
    }
    
    private func saveRecipe() {
        // 这里写你的保存逻辑,比如存CoreData或者调用API
    }
    
    private func resetRecipe() {
        recipeClass.recipeTitle = ""
        recipeClass.recipePrepTime = ""
        recipeClass.recipeCarbMacro = 0
        recipeClass.recipeCaloriesMacro = 0
        recipeClass.recipeFatMacro = 0
        recipeClass.recipeProteinMacro = 0
    }
}

3. 可选优化:根视图用@StateObject管理Recipe

如果你的项目是iOS14及以上版本,把根视图的@ObservedObject改成@StateObject,确保数据对象的生命周期和视图绑定:

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为@StateObject(iOS14+)
    @StateObject var recipeClass = Recipe()
    var onDismiss: (() -> Void)?
   
    var body: some View {
        // 原有代码保持不变
    }
}

内容的提问来源于stack exchange,提问作者Swink

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 14:20:40