SwiftUI:如何使用延迟在两个图像之间设置动画过渡?

Posted

技术标签:

【中文标题】SwiftUI:如何使用延迟在两个图像之间设置动画过渡?【英文标题】:SwiftUI: how to animate transition between two Images using a delay? 【发布时间】:2020-10-12 11:40:29 【问题描述】:

我有两张图片,ImageAImageB,我的目标是通过以下方式为它们之间的过渡设置动画:

    ImageA 已加载 暂停 1 秒 ImageA 转换为 ImageB,持续时间为 1.5 秒

对于常规 Swift,它将使用带有动画持续时间和暂停的 UIView.animate 闭包。

这是我对 SwiftUI 的尝试,它没有显示平滑过渡,而是显示了硬图像更改:

VStack(alignment: .leading, spacing: 0) 
            Image(images.randomElement()!)
                    .resizable()
                    .scaledToFill()
                    .onAppear 
                        DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) 
                        withAnimation()  //added
                            self.shouldTransition.toggle()
                        
                    
                    
            if shouldTransition 
                Image(images.randomElement()!)
                        .resizable()
                        .animation(.easeInOut(duration: 1.5))
                        .scaledToFill()
            
            
        

我在实现图像过渡动画时缺少什么?

编辑:整个代码库可以在这里找到:TestWidget Github

【问题讨论】:

【参考方案1】:

您必须在观察到的变化周围添加 withAnimation() ... 包装器,您希望对其进行动画处理。

将您的代码更改为

DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) 
                                withAnimation()
                                self.shouldTransition.toggle()
                                
                            

【讨论】:

感谢您的建议。我添加了withAnimation(),但图像过渡仍然没有显示动画而是突然的图像变化。我还更新了问题正文中的代码。【参考方案2】:

你不指定你想要哪种过渡,默认情况下 SwiftUI 使用不透明度...

试试下面的

VStack(alignment: .leading, spacing: 0) 
    if !shouldTransition 
        Image(images.randomElement()!)
            .resizable()
            .scaledToFill()
            .onAppear 
                DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) 
                    self.shouldTransition.toggle()
                
            
            //.transition(.move(edge: .top))      // uncomment to modify transition
    

    if shouldTransition 
        Image(images.randomElement()!)
            .resizable()
            .scaledToFill()
            //.transition(.move(edge: .top))      // uncomment to modify transition
    
    
.animation(.easeInOut(duration: 1.5), value: shouldTransition)

【讨论】:

感谢分享。这绝对看起来很有希望,但不幸的是结果相同:图像更改之间没有动画(我取消了代码中每个 cmets 的两个 .transition()s 的注释)。我已经上传了整个代码库并更新了问题正文 我错过了这是小部件......它在小部件中不起作用 - 它是静态渲染的。 我明白了——这就解释了。感谢您分享您的见解

以上是关于SwiftUI:如何使用延迟在两个图像之间设置动画过渡?的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI 反向动画延迟移除

延迟 SwiftUI 中的重复动画,在完整的自动反转重复周期之间

SwiftUI动画:如何移动然后显示?

如何在 SwiftUI 中为 Start->Max->Start 设置动画?

SwiftUI - 在当前视图中为新图像设置动画

iOS:在两个动画视图之间画线