簡體   English   中英

如何強制在 SwiftUI 中出現顯式 animation

[英]How to force an explicit animation to occur in SwiftUI

我創建了這個視圖修改器,它基於 boolean 綁定對視圖偏移的變化進行動畫處理,並在 animation 完成時自行重置(同時重置 boolean 綁定)。

struct OffsetViewModifier: AnimatableModifier {
    let amount: Double  // amount of offset
    @Binding var animate: Bool  // determines if the animation should begin
    
    private(set) var pct = 0.0  // percentage of the animation complete
    
    var animatableData: Double {
        get { animate ? 1.0 : 0.0 }
        set { pct = newValue }
    }
    
    func body(content: Content) -> some View {
        content
            .offset(x: amount * pct)
            .onChange(of: pct) { newValue in
                if newValue == 1.0 {  // If newValue is 1.0 that means animation is complete
                    withAnimation(.none) { animate = false }  // When animation completes, reset binding
                    // Since I don't want this to cause an animation, I wrap it with withAnimation(.none)
                }
            }
    }
}

我像這樣使用這個新的修飾符:

VStack {
    Text(tapped.description)
    Circle()
        .frame(width: 100, height: 100)
        .onTapGesture {
            tapped = true
        }
        .modifier(OffsetViewModifier(amount: 50, animate: $tapped))
        .animation(Animation.linear(duration: 3), value: tapped)
}

但是, withAnimation(.none)不起作用,並且此視圖仍需要 3 秒才能重置。

如何強制發生顯式 animation 而不是.linear(duration: 3)一個?

提前致謝。

如果我理解正確的話,你應該做的是在tapped.animation withAnimation像這樣修改整個視圖。 tapped 綁定到 animate,當您在修改器中更改 animate 的值時,您正在更改 tapped 的值,因此,執行線性 animation

VStack {
    Text(tapped.description)
    Circle()
        .frame(width: 100, height: 100)
        .onTapGesture {
            withAnimation(.linear(duration: 3)) {
                tapped = true
            }
        }
        .modifier(OffsetViewModifier(amount: 50, animate: $tapped))
}

我個人的建議是避免使用.animation(),因為就像我之前說的那樣,它會為整個視圖設置動畫,並會導致像這樣的問題

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM