简体   繁体   English

如何强制在 SwiftUI 中出现显式 animation

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

I created this View modifier which animates a change in the offset of a view based on a boolean Binding and resets itself when the animation finishes (also resetting the boolean Binding).我创建了这个视图修改器,它基于 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)
                }
            }
    }
}

I used this new modifier like this:我像这样使用这个新的修饰符:

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)
}

However, the withAnimation(.none) didn't work, and this view still takes 3 seconds to reset.但是, withAnimation(.none)不起作用,并且此视图仍需要 3 秒才能重置。

How do I force the explicit animation to occur and not the .linear(duration: 3) one?如何强制发生显式 animation 而不是.linear(duration: 3)一个?

Thanks in advance.提前致谢。

If I understood this correctly, what you should do is wrap tapped within withAnimation because the .animation is modifying the whole view like this.如果我理解正确的话,你应该做的是在tapped.animation withAnimation像这样修改整个视图。 tapped is binded to animate, when you change animate's value in the modifier, you're changing the value of tapped, therefore, executing the linear animation 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))
}

My personal advice is to avoid using.animation() because like I said before it will animate the entire view and will cause problems like this one我个人的建议是避免使用.animation(),因为就像我之前说的那样,它会为整个视图设置动画,并会导致像这样的问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM