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

如何避免值未变更时重复写入SwiftUI Preference?

解决方案:在PreferenceKey中添加值相等判断

你可以直接修改ViewSizePreferenceKey的reduce方法,仅当新尺寸与当前保存的值不同时,才更新Preference的值。这样SwiftUI就不会因为重复的相同值触发不必要的onPreferenceChange回调,从根源上解决重复写入和警告问题。

修改后的PreferenceKey代码:

struct ViewSizePreferenceKey: PreferenceKey {
  static var defaultValue: CGSize = .zero
  static func reduce(value: inout CGSize, nextValue: () -> CGSize) {
    let newValue = nextValue()
    // 仅当新尺寸与当前值不同时更新
    if newValue != value {
      value = newValue
    }
  }
}

补充说明:

  1. 浮点精度问题处理:如果你的视图尺寸涉及浮点计算,可能会出现精度误差,此时可以用CGSize的equalTo(_:)方法做精确匹配,或者自定义近似相等判断:
// 扩展CGSize添加近似相等方法
extension CGSize {
  func isApproximatelyEqual(to other: CGSize, tolerance: CGFloat = 0.001) -> Bool {
    abs(width - other.width) < tolerance && abs(height - other.height) < tolerance
  }
}

// 修改reduce中的判断逻辑
static func reduce(value: inout CGSize, nextValue: () -> CGSize) {
  let newValue = nextValue()
  if !newValue.isApproximatelyEqual(to: value) {
    value = newValue
  }
}
  1. 原理说明:SwiftUI的Preference更新机制中,只有当reduce方法最终修改了value的值时,才会触发onPreferenceChange回调。通过在reduce中添加相等判断,我们拦截了重复的相同值更新,避免了无意义的回调和Xcode警告。

你的视图扩展代码不需要做任何修改,就能直接受益于这个优化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 16:05:09