SwiftUI中保留@State变量修改前旧值的最佳实现方案
保留SwiftUI中@State变量旧值的几种实用方法
针对你需要保留TextField修改的@State变量旧值的需求,下面是几种直接可行的实现方式:
方法一:用独立@State变量存储旧值
适合变量数量不多的场景,初始化时把当前值同步到旧值变量,之后通过onChange监听原变量的变化,每次变化前更新旧值:
struct ContentView: View { @State var name: String = "初始名字" @State private var oldName: String = "" var body: some View { TextField("输入名字", text: $name) .onAppear { // 初始化时同步旧值 oldName = name } .onChange(of: name) { previousValue in // 每次值变化前,先把上一次的值存为旧值 oldName = previousValue } Button("恢复旧值") { name = oldName } } }
方法二:用ObservableObject封装状态与旧值
如果有多个需要保留旧值的变量,用ViewModel封装会更整洁,避免View里变量混乱:
class FormViewModel: ObservableObject { @Published var name: String = "初始名字" @Published var age: String = "20" // 存储旧值的变量 private(set) var oldName: String = "" private(set) var oldAge: String = "" init() { // 初始化旧值 syncOldValues() } // 手动调用更新旧值,也可结合监听Published变量自动触发 func syncOldValues() { oldName = name oldAge = age } } struct ContentView: View { @StateObject private var viewModel = FormViewModel() var body: some View { VStack { TextField("输入名字", text: $viewModel.name) TextField("输入年龄", text: $viewModel.age) Button("保存并更新旧值") { // 先使用旧值做业务操作,再同步旧值为当前新值 print("旧名字:\(viewModel.oldName),新名字:\(viewModel.name)") viewModel.syncOldValues() } Button("恢复旧值") { viewModel.name = viewModel.oldName viewModel.age = viewModel.oldAge } } } }
方法三:自定义Property Wrapper(进阶)
如果多个页面都需要保留旧值的功能,可以封装一个自定义Property Wrapper,自动管理当前值和旧值:
@propertyWrapper struct TrackableState<Value> { @State private var currentValue: Value private(set) var oldValue: Value init(wrappedValue: Value) { self.currentValue = wrappedValue self.oldValue = wrappedValue } var wrappedValue: Value { get { currentValue } set { oldValue = currentValue currentValue = newValue } } var projectedValue: Binding<Value> { $currentValue } } struct ContentView: View { @TrackableState var name: String = "初始名字" var body: some View { TextField("输入名字", text: $name) Button("查看新旧值") { print("旧值:\(name.oldValue),新值:\(name.wrappedValue)") } } }
注意事项
- 如果需要在TextField输入过程中实时保留旧值,用
onChange或者自定义Property Wrapper的方式更合适; - 如果只需要在确认操作(比如点击保存按钮)前保留旧值,直接在操作前手动把当前值赋值给旧值变量即可,无需实时监听。
内容的提问来源于stack exchange,提问作者Cipri
相关产品推荐
相关产品推荐

