Swift使用onChange监听状态变化
Swift使用onChange监听状态变化

Swift使用onChange监听状态变化

onChange 是 SwiftUI 中的一个视图修饰符,用于监听某个状态值的变化。当指定的值发生变化时,onChange 会执行提供的代码块。

使用场景

在 SwiftUI 中,.onAppear 只会在视图首次加载时被触发,但有时可能希望在某个状态值(如布尔值、变量等)发生变化时执行特定操作。这时就可以使用 .onChange。

假设有一个 @State 变量 isActive,希望在 isActive 变为 true 或 false 时执行一些操作:

@State private var isActive: Bool = false

var body: some View {
    VStack {
        Toggle("Activate", isOn: $isActive)
            .padding()
    }
    .onChange(of: isActive) { oldValue, newValue in
        if newValue {
            print("isActive 切换为 true,执行某些操作")
        } else {
            print("isActive 切换为 false,执行其他操作")
        }
    }
}

在这个例子中,每当 isActive 的值改变时,onChange 的闭包都会被调用,newValue 会是 true 或 false。

问题报错

在使用onChange的过程中可能存在如下报错:

'onChange(of:perform:)' was deprecated in iOS 17.0: Use `onChange` with a two or zero parameter action closure instead.

这是因为onChange的一个形式被标记为废弃。

背景与废弃的 onChange() 变体

在 iOS 16 及更早版本中,onChange 有以下三种常见形式:

1、接受旧值和新值的完整形式(推荐形式,从 iOS 14 开始支持):

.onChange(of: someValue) { oldValue, newValue in
    // 响应变化,并可使用旧值和新值
}

2、只接受新值的简化形式(被标记为废弃,从 iOS 17 开始不建议使用):

.onChange(of: someValue) { newValue in
    // 响应变化,只使用新值
}

3、不接受参数的形式(适用于只关心变化但不需要新值的场景):

.onChange(of: someValue) {
    // 响应变化,不需要访问值
}

Apple 从 iOS 17 开始废弃了第二种只接受新值的形式。废弃的原因是开发者往往需要同时访问旧值和新值,而简化形式可能导致不必要的限制。

替代方案

Apple 并没有提供新的替代方案,因为第一种形式(接受旧值和新值)已经能够满足所有需求,同时保留了灵活性。因此,推荐使用以下形式:

.onChange(of: someValue) { oldValue, newValue in
    // 使用旧值和新值执行逻辑
}

如果并不需要旧值,只关心新值,也可以忽略旧值的使用:

.onChange(of: someValue) { _, newValue in
    print("New value is \(newValue)")
}

是否可以继续使用已废弃的形式?

向后兼容性:如果需要支持 iOS 16 及更早版本,仍然可以使用废弃的形式。这种形式在旧版本中是完全可用的。

未来支持风险:废弃的形式在未来可能被完全移除,因此对于只面向 iOS 17+ 的应用,不建议继续使用这种形式。

废弃的形式仍然可以正常工作,但为了确保代码的可维护性,最好迁移到推荐形式。

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开放者。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注