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

SwiftUI切换视图时如何保留TextEditor中的输入文本?

解决SwiftUI中TextEditor切换视图后文本丢失的问题

问题根源在于你用的@State变量生命周期和当前视图绑定,当切换到其他视图导致VistaDatos被销毁时,@State存储的opinion会被重置,返回后自然丢失文本。

下面是几种可行的解决方案:

1. 用@AppStorage持久化到本地(最简单的持久化方案)

把@State替换为@AppStorage,它会自动将数据存在UserDefaults中,即使APP重启数据也不会丢失:

struct VistaDatos: View {
    // 替换@State为@AppStorage,指定唯一存储键名
    @AppStorage("userOpinion") private var opinion: String = ""
    
    var progreso : Double {
        Double(opinion.count)
    }
    
    var body: some View {
        // 原有代码保持不变...
    }
}

2. 状态提升到父视图(临时共享数据)

如果不需要持久化,仅需在APP运行期间保留数据,把opinion变量移到父视图,用@Binding传递给当前视图:

父视图示例:

struct ParentView: View {
    @State private var parentOpinion: String = ""
    
    var body: some View {
        NavigationStack {
            VistaDatos(opinion: $parentOpinion)
            // 其他视图切换逻辑...
        }
    }
}

修改后的VistaDatos:

struct VistaDatos: View {
    @Binding var opinion: String
    
    var progreso : Double {
        Double(opinion.count)
    }
    
    var body: some View {
        // 原有代码保持不变...
    }
}

3. 使用ObservableObject作为ViewModel(复杂状态管理)

如果多个视图需要访问或修改该文本,或需要更复杂的状态逻辑,用ViewModel统一管理数据:

创建ViewModel类:

class OpinionViewModel: ObservableObject {
    @Published var opinion: String = ""
}

修改后的VistaDatos:

struct VistaDatos: View {
    // iOS14+用@StateObject,更早版本用@ObservedObject
    @StateObject private var viewModel = OpinionViewModel()
    
    var progreso : Double {
        Double(viewModel.opinion.count)
    }
    
    var body: some View {
        VStack{ 
            // ...原有代码...
            VStack{
                TextEditor(text: $viewModel.opinion) // 绑定到viewModel的opinion
                    // ...原有修饰符保持不变...
                    .onChange(of: viewModel.opinion) { value in
                        if value.count > 150 {
                            viewModel.opinion = String(value.prefix(150))
                        }
                    }
                
                Text("Número de palabras: \(Int(progreso))/150")
                    .foregroundColor(Int(progreso) >= 100 ? .red : .white)
                ProgressView(value: progreso, total: 150) {
                }.frame(width: 350, alignment: .center)
            }
        }.background(Color.green)
        Spacer()
    }
}

根据需求选择对应方案:

  • 需持久化简单数据选方案1
  • 临时跨视图共享数据选方案2
  • 复杂状态管理或多视图共享选方案3

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 05:05:21