在子视图中有以下两个属性:
- 是初始化为false的local@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
的原因是因为属性的值没有更改。您必须为基础_parentValue
属性分配一个新的Binding
。相反,您可以定义一个新的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 }