SwiftUI:停止一个永远重复的动画

标签 swift xcode swiftui

我想在屏幕上有一个“徽章”,当条件满足时,它会从正常大小反弹到更大,然后反复恢复正常,直到不再满足条件。不过,我似乎无法让徽章停止“弹跳”。 一旦开始,势不可挡。

我试过的:
我尝试使用了一些动画,但它们可以分为使用“repeatForever”来达到预期效果的动画和不使用“repeatForever”的动画。例如:
Animation.default.repeatForever(autoreverses: true)

Animation.spring(response: 1, dampingFraction: 0, blendDuration: 1) (将阻尼设置为 0 使其永远消失)

然后用 .animation(nil) 把它换掉。似乎不起作用。有没有人有任何想法?非常感谢您提前!这是重现它的代码:

struct theProblem: View {
    @State var active: Bool = false

    var body: some View {
        Circle()
            .scaleEffect( active ? 1.08: 1)
            .animation( active ? Animation.default.repeatForever(autoreverses: true): nil )
            .frame(width: 100, height: 100)
            .onTapGesture {
                self.active = !self.active

        }
    }
}

最佳答案

我想到了!

使用 的动画.repeatForever() 如果您用 替换动画,将不会停止nil . 如果你用相同的动画替换它,但没有 ,它会停止.repeatForever() . (或者使用任何其他停止的动画,因此您可以使用持续时间为 0 的线性动画来立即停止)

换句话说,这将不起作用:.animation(active ? Animation.default.repeatForever() : nil)
但这确实有效:.animation(active ? Animation.default.repeatForever() : Animation.default)
为了使它更易读和易于使用,我把它放到一个扩展中,你可以这样使用: .animation(Animation.default.repeat(while: active))
这是一个使用我的扩展程序的交互式示例,您可以使用实时预览来测试它:

import SwiftUI

extension Animation {
    func `repeat`(while expression: Bool, autoreverses: Bool = true) -> Animation {
        if expression {
            return self.repeatForever(autoreverses: autoreverses)
        } else {
            return self
        }
    }
}

struct TheSolution: View {
    @State var active: Bool = false
    var body: some View {
        Circle()
            .scaleEffect( active ? 1.08: 1)
            .animation(Animation.default.repeat(while: active))
            .frame(width: 100, height: 100)
            .onTapGesture {
                self.active.toggle()
            }
    }
}

struct TheSolution_Previews: PreviewProvider {
    static var previews: some View {
        TheSolution()
    }
}

据我所知,一旦您分配动画,它永远不会消失,直到您的 View 完全停止。因此,如果您有一个 .default 动画设置为永远重复并自动反转,然后您分配一个持续时间为 4 的线性动画,您会注意到默认的重复动画仍在进行,但它的运动变得越来越慢,直到它在我们的 4 秒结束时完全停止。因此,我们通过线性动画将默认动画设置为停止动画。

关于SwiftUI:停止一个永远重复的动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59133826/

相关文章:

ios - 在 SwiftUI 中带有导航栏标题的 EXC_BAD_ACCESS

ios - s 为什么我的 Product->Archive 会在不同上下文中的对象之间出现 'Illegal attempt to establish a relationship ' compressionType' 失败?

ios - swift : Separate classes for network requests

swift - 如何在 Swift 3 中使用非公历系统初始化日历?

ios - 从 applicationWillEnterForeground 重新加载 TableView

swiftui - MFMessageComposeViewController + SwiftUI 错误行为

ios - 当 View 重新进入前景时恢复绘制 CAShapeLayer?

xcode - 将 Swift 中 HTTP 请求返回的 NSData 转换为字符串

iphone - iPhone 应用程序内的多种语言选择选项

swiftui - 为什么绑定(bind)到 UIViewRepresentable 的注入(inject)会导致内存泄漏?