微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么使用SwiftUI中的Binding属性,didSet无法按预期工作

如何解决为什么使用SwiftUI中的Binding属性,didSet无法按预期工作

我在子视图中具有以下两个属性

  1. 一个本地@State var localValue,已初始化为false
  2. 一个@Binding var parentValue属性,该属性正在由父视图切换。

我想在我的代码中使用localValue,因为它以false开头,然后在初始化视图时切换为true,这将启动动画,该动画需要以false开头。 parentValue属性在父视图中切换,我希望它更新我的localValue属性以正确控制动画。虽然parentValue确实在切换localValue属性,但didSet似乎并没有改变它。我想念什么?

@State var localValue = false

@Binding var parentValue: Bool {
    didSet {localValue = parentValue}
}

根据评论进行更详细的更新

如果由于@Binding包装器本身没有更改,因此没有触发didSet导致无法执行此操作,那么我需要的是类似的东西。

我想拥有一个最初设置为false但可以从外部视图切换的属性,以便控制子视图中的动画,该动画根据切换的值来改变方向。

如果我可以将子视图中的bound属性初始化为false,即是否有某种设置方法

@Binding var breath: Bool = false 

作为起始值,则每次父级切换切换parentValue属性时,子级视图都会正确响应。现在,父视图调用属性设置为true的子视图,这意味着动画将完全展开,而我希望第一步是使动画在特定持续时间内增长,然后在父视图将值设置为false时反转还有其他持续时间的数量

    // Whole flower
                .rotationEffect(.degrees(breath ? 360 : 0),anchor: .center) // Inhale = clockwise rotation,Exhale = anticlockwise rotation
                .scaleEffect(breath ? 1 : 0.2) // Inhale = upscale,Exhale = downscale
                .animation( Animation.easeInOut(duration: self.stepDuration))
                .opacity(breath ? 1 : 0.75)

请参阅上面的代码,以了解为什么重要的一点是,当视图开始时动画的缩放比例为0.2,然后在持续时间到期且呼吸属性已切换为false时,在反转之前先放大为全尺寸。 / p>

解决方法

未调用 didSet 的原因是该属性的值未更改。您必须为基础 Binding 属性分配一个新的 _parentValue。相反,您可以定义一个新的 Binding 属性来改变 parentValue 属性并调用自定义闭包。一个简单的方法是定义一个像这样的扩展方法:

extension Binding {
    func didSet(_ closure: @escaping (Value) -> ()) -> Binding<Value> {
        Binding(
            get: { self.wrappedValue },set: {
                self.wrappedValue = $0
                closure($0)
            }
        )
    }
}

然后当您初始化您的属性时,您可以执行以下操作:

self.parentValue = $someBinding.didSet { localValue = $0 }

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。