繁体   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