iOS 14 SwiftUI中不需要的位置动画

时间:2020-09-06 16:29:15

标签: ios swift animation swiftui

对于iOS 14和iOS 13,快速UI动画的行为似乎与父框架中View位置的动画有所不同。 我在以下代码段中的目标是仅对按钮文本的大小进行动画处理,这应该在点击按钮时发生。 取而代之的是,在iOS 14中,按钮的位移(由VStack中附加视图的可见性切换引起)也得到了动画处理。

相同的代码在iOS 13(Xcode 11)和iOS 14(macOS 11 beta中的Xcode 12 beta 6)中产生不同的输出。 在iOS 14中,如何重现旧的行为?

import SwiftUI
import PlaygroundSupport

struct ContentView: View {
    @State var toggle = false
    var body: some View {
        VStack{
            if self.toggle {
                Rectangle().frame(width: 200, height: 200)
            }
            Button(action: {
                self.toggle.toggle()
            }){
                Text("Tap me!")
                    .scaleEffect(self.toggle ? 2 : 1)
                    .animation(
                        Animation.easeInOut(duration: 1.5)
                    )
            }
        }
        .frame(width: 400, height: 400)
    }
}

PlaygroundPage.current.setLiveView(ContentView())

这是所需的行为,例如在iOS 13中 iOS 13 behavior

这是有害行为,如iOS 14 iOS 14 behavior

请注意,至少对于我来说,不仅在Playground中,而且在Xcode Previews中的Simulator和Device中,对于iOS 14也会发生相同的不良行为(请参阅项目文件https://github.com/himbeles/PositionAnimationExample) : iOS 14 behavior Xcode Preview

1 个答案:

答案 0 :(得分:1)

如果您在macOS Catalina或macOS Big Sur上使用Xcode 12,则这是一种行为更改,在iOS 14,macOS Big Sur和Swift Playground中可见。

您只希望缩放缩放动画。

一种解决方法是更改​​为显式动画,并使用其他toggle控制缩放。然后用scale.toggle来包裹withAnimation { }的切换:

struct ContentView: View {
    @State var toggle = false
    @State var scale = false
    var body: some View {
        VStack{
            if self.toggle {
                Rectangle().frame(width: 200, height: 200)
            }
            Button(action: {
                self.toggle.toggle()
                withAnimation(.easeInOut(duration: 1.5)) {
                    self.scale.toggle()
                }
            }){
                Text("Tap me!")
                    .scaleEffect(self.scale ? 2 : 1)
            }
        }
        .frame(width: 400, height: 400)
    }
}