为什么didSet在SwiftUI中的绑定属性不能正常工作

为什么didSet在SwiftUI中的绑定属性不能正常工作,swiftui,xcode11,Swiftui,Xcode11,我在子视图中具有以下两个属性: 是初始化为false的本地@State var localValue 是父视图正在切换的@Binding var parentValue属性 我想在代码中使用localValue,因为它以false开头,然后在初始化视图时切换为true,这将启动需要以false开头的动画。parentValue属性在父视图中切换,我希望它更新我的localValue属性以正确控制动画。尽管parentValue确实在切换localValue属性,但它似乎并没有随didSet而改变

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

  • 是初始化为false的本地@State var localValue
  • 是父视图正在切换的@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,但可以从外部视图切换,以便控制子视图中的动画,该动画根据切换的值更改方向

    如果我可以将子视图中的绑定属性初始化为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时,动画会在反转之前增长为全尺寸,这一点很重要。

    未调用didSet的原因是因为属性的值未更改。您必须将新的
    绑定
    分配给基础的
    \u parentValue
    属性。相反,您可以定义一个新的
    绑定
    属性,该属性可以改变
    parentValue
    属性并调用自定义闭包。一种简单的方法是定义如下扩展方法:

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

    因为它们是带有外部存储的特殊属性包装器-它们不会被更改,所以不会调用didSet。谢谢。那么是否有一些方法可以直接初始化@Binding变量,以便它从一个值(例如false)开始,然后假设父视图设置的值?是的,有。你能举个例子说明你在做什么吗?苹果公司必须把这些垃圾统一起来,这些垃圾基本上都是一样的垃圾,只会让一切成为噩梦。
    self.parentValue = $someBinding.didSet { localValue = $0 }