如何在SwiftUI中强制视图重新渲染?

pvcm50d1  于 2023-04-19  发布在  Swift
关注(0)|答案(1)|浏览(168)

我有以下代码

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的库

ljsrvy3e

ljsrvy3e1#

我看了一下库,相信是因为ConfettiCannon中的这个错误:

// first converts your confettis to shapes.

_confettiConfig = StateObject(wrappedValue: ConfettiConfig(
 num: num,
 shapes: shapes,

StateObject是一个“真理的来源”,因此不能依赖于任何可能改变的输入,而在你的情况下它确实会改变。wrappedValue是一个只被调用一次的自动闭包,因此它只接收你的五彩纸屑形状的第一个版本(和你所有的其他参数),并且不知道你的改变。
在他们的demo项目中,他们通过sheet显示五彩纸屑,这将在关闭时清除@StateObject并在下一个演示中创建一个新的,所以你可以做同样的事情。否则提交一个issue请求允许在演示时修改ConfettiConfig
如果这只是一个有趣的项目,作为一个快速的黑客,在.confettiCannon之后,你可以使用.id(confettiCounter),这将迫使它更新,但以一种非常低效的方式。

相关问题