【问题标题】:Unwanted position animation in iOS 14 SwiftUIiOS 14 SwiftUI 中不需要的位置动画
【发布时间】:2020-09-06 16:29:15
【问题描述】:

对于 iOS 14 和 iOS 13,Swift UI 动画在其父框架中的 View 位置的动画表现似乎有所不同。 我在下面的代码 sn-p 中的目标是仅动画调整按钮文本的大小,这应该在点击它时发生。 相反,在 iOS 14 中,按钮的位移(由 VStack 中的一个附加视图的切换可见性引起)也被动画化了。

相同的代码在 iOS 13(Xcode 11)和 iOS 14(Xcode 12 beta 6,macOS 11 beta)中产生不同的输出。 在 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 14 中一样

请注意,至少对我而言,同样的不良行为不仅发生在 Playground 中,还发生在 Xcode Previews 中的 iOS 14 以及模拟器和设备上(参见项目文件 https://github.com/himbeles/PositionAnimationExample):

【问题讨论】:

  • 我认为这是 Playground 问题(此类事情发生在过渡/动画中)。在预览和模拟器中与 Xcode 12b5 / iOS 14 配合使用。
  • 感谢您的反馈。嗯,不幸的是,不适合我,使用 Xcode 12 beta 6、iOS 14。既不是在设备上也不是在模拟器上。
  • 它在 iOS14 中也适用于我。我正在看到所需的预览。一定是因为你在 PlaygroundPage 中预览.... PlaygroundPage.current.setLiveView(ContentView())
  • 感谢您的所有反馈。但对我来说,它与游乐场无关。我已更新问题以包含直接在新的 XCode 12 beta 6 项目中运行的代码的屏幕截图,没有任何游乐场代码。

标签: ios swift animation swiftui


【解决方案1】:

如果您在 macOS Catalina 或 macOS Big Sur 上使用 Xcode 12,则这是在 iOS 14、macOS Big Sur 和 Swift Playground 中可见的行为变化。

您只希望缩放动画。

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

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

【讨论】:

  • 您的解决方法效果很好,再次感谢。对我来说,原始代码中的动画“行为不端”也发生在模拟器和设备上,也没有游乐场代码。请问您是从哪个平台编译的?我在 macOS 11 b6 上使用 XCode 12 b6,为 iOS 14 编译(b6 模拟器,设备上的 b7)。
  • 我明白了。我在 macOS Catalina 上使用 Xcode 12b6 进行编译,而我的 iPhone 运行的是 iOS 13。所以这显然是 iOS 14/mac OS 11 的行为变化,所以我只在 Playground 中看到它。很高兴知道。谢谢!
  • 我希望这种变化不会一直存在。我发现这种行为非常违反直觉,考虑到视图的位置通常由父视图处理,而动画修改器位于子视图中。
  • 不幸的是,我仍然在 Xcode 12.4 中看到这种行为。我尝试在.onAppear() 中使用withAnimation 作为workaraound,但这似乎出于某种原因使整个父视图的外观动画化:/
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多