我有以下代码
struct TriggerButton: View {
@State private var confettiCounter: Int = 0
@Binding var mode: ConfettiMode
@Binding var showText: Bool
@State private var counter = 0
var body: some View {
VStack {
Button {
confettiCounter += 1
if showText {
withAnimation(.easeIn(duration: 0.5)) {
showText = false
}
}
counter += 1
if counter == 3 {
counter = 0
mode = mode.next()
}
} label: {
Text(mode.icon)
.font(.system(size: 100))
.shadow(radius: 15, x: 5, y: 5)
}
.confettiCannon(counter: $confettiCounter, num: 70, confettis: mode.items, colors: [.red, .green, .yellow, .pink, .purple, .orange], confettiSize: 10, rainHeight: 300, openingAngle: Angle.degrees(30), closingAngle: Angle.degrees(150), radius: 500)
}
}
}
当模式改变时,我希望视图被渲染。但是,mode.icon得到更新,而confettiCannon中的mode.items没有。为什么会这样?如何修复?
Confetti是来自https://github.com/simibac/ConfettiSwiftUI的库
1条答案
按热度按时间ljsrvy3e1#
我看了一下库,相信是因为
ConfettiCannon
中的这个错误:StateObject
是一个“真理的来源”,因此不能依赖于任何可能改变的输入,而在你的情况下它确实会改变。wrappedValue
是一个只被调用一次的自动闭包,因此它只接收你的五彩纸屑形状的第一个版本(和你所有的其他参数),并且不知道你的改变。在他们的demo项目中,他们通过
sheet
显示五彩纸屑,这将在关闭时清除@StateObject
并在下一个演示中创建一个新的,所以你可以做同样的事情。否则提交一个issue请求允许在演示时修改ConfettiConfig
。如果这只是一个有趣的项目,作为一个快速的黑客,在
.confettiCannon
之后,你可以使用.id(confettiCounter)
,这将迫使它更新,但以一种非常低效的方式。