嵌入时忽略 SwiftUI 堆叠属性动画

Posted

技术标签:

【中文标题】嵌入时忽略 SwiftUI 堆叠属性动画【英文标题】:SwiftUI stacked property animations ignored when embedded 【发布时间】:2019-11-08 12:29:23 【问题描述】:

通过示例,我们可以看到可以使用不同的动画为不同的属性设置动画。例如:

Button("Tap me") self.isShowingRed.toggle()
    .frame(width: 200, height: 200)
    .background(isShowingRed ? Color.red : Color.blue)
    .animation(.easeIn(duration: 2.5))
    .clipShape(RoundedRectangle(cornerRadius: isShowingRed ? 50 : 0))
    .animation(Animation.easeInOut(duration: 0.1).repeatCount(5))

此代码将在 2.5 秒内将按钮背景从红色变为蓝色,同时将圆角半径从 0 变为 50,重复 5 次。

视图一嵌入问题就出现了:

VStack 
    Button("Tap me") self.isShowingRed.toggle()
        .frame(width: 200, height: 200)
        .background(isShowingRed ? Color.red : Color.blue)
        .animation(.easeIn(duration: 2.5))
        .clipShape(RoundedRectangle(cornerRadius: isShowingRed ? 50 : 0))
        .animation(Animation.easeInOut(duration: 0.1).repeatCount(5))
     

当按钮被嵌入时,只使用第一个动画,在这种情况下,颜色和半径都将在 2.5 秒内完成动画,没有重复。

即使我将按钮设为单独的组件,同样的问题仍然存在。

是我做错了什么还是 SwiftUI 的错误?

编辑:我正在使用 Xcode 11.1 并在模拟器上进行测试。

【问题讨论】:

在 xCode 11.2 中似乎没有任何变化,按钮是否嵌入 VStack 无关紧要 【参考方案1】:

正如我所观察到的,当存在 .background 时发生意外情况时,问题就出在其中...在您的用例中,必须将动画应用于背景内容,这可以解决问题。

这是我使用的示例,它可以根据您的需要进行动画处理,并且没有容器。

import SwiftUI

struct TestButtonAnimation: View 
    @State private var isShowingRed = false
    var body: some View 
        VStack 
            Button("Tap me") self.isShowingRed.toggle()
                .frame(width: 200, height: 200)
                .background(
                    Group isShowingRed ? Color.red : Color.blue
                    .animation(.easeIn(duration: 2.5))
                )
                .clipShape(RoundedRectangle(cornerRadius: isShowingRed ? 50 : 0))
                .animation(Animation.easeInOut(duration: 0.1).repeatCount(5))
        
    


struct TestButtonAnimation_Previews: PreviewProvider 
    static var previews: some View 
        TestButtonAnimation()
    

测试:Xcode 11.1

【讨论】:

虽然这是background 的解决方法,但同样的问题可以通过offset 和其他无法嵌入动画的属性重现。【参考方案2】:

您可以在容器中尝试这种方式.animation(.default)

  var body: some View 
  VStack
  Button("Tap me") self.isShowingRed.toggle()
 .frame(width: 200, height: 200)
 .background(isShowingRed ? Color.red : Color.blue)
 .animation(.easeIn(duration: 2.5))
.clipShape(RoundedRectangle(cornerRadius: isShowingRed ? 50 : 0))
.animation(Animation.easeInOut(duration: 0.1).repeatCount(5))
.animation(.default)

【讨论】:

【参考方案3】:

更新到 Xcode 11.2.1 后,此问题已解决。

【讨论】:

以上是关于嵌入时忽略 SwiftUI 堆叠属性动画的主要内容,如果未能解决你的问题,请参考以下文章

一行代码解决CoreData托管对象属性变更在SwiftUI中无动画效果的问题

SwiftUI onAppear:动画持续时间被忽略

嵌入另一个视图时,SwiftUI 动画不起作用

来自 @Published 属性的 SwiftUI 动画从视图外部更改

SwiftUI:输入无效时文本字段抖动动画

关键帧中的非动画属性在 iOS 上被忽略