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
相关产品推荐
相关产品推荐

