无法在表单中控制动画?

bko*_*cik 6 ios swift swiftui swiftui-form

这不是意味着可以控制表单视图内发生的动画吗?我这里有一个 Playground 来演示这个问题,并附有一张发生情况的 gif 动图。如您所见,我在第二个动画视图上的过渡完全被忽略,并且我必须手动放慢视频速度,因为持续时间也被忽略。

我并不是真的想要缩放过渡,这只是为了证明无论我在那里放置什么,动画都是相同的。这是预期的结果,还是一个错误?或者我只是做了一些完全错误的事情?

我也不清楚为什么 VStack 的动画处理方式与简单的文本字段如此不同,后者可以很好地向下滑动,而 VStack 似乎得到了 .move 和 .opacity 的某种组合。

动画演示

import SwiftUI
import PlaygroundSupport


struct ContentView: View {

    @State var showGoodAnimation = false
    @State var showBadAnimation = false

    var body: some View {
        Form {
            Toggle(isOn: self.$showGoodAnimation.animation(.easeInOut(duration: 1))) {Text("Yay!")}
            if self.showGoodAnimation {
                Text("I animate beautifully.")
            }
            Toggle(isOn: self.$showBadAnimation.animation(.easeInOut(duration: 1))) {Text("Boo!")}
            if self.showBadAnimation {
                VStack {
                    Text("Hi.").padding()
                    Text("I'm a hot mess.").padding()
                }
                .frame(height: 250)
                .transition(.scale)
            }
            Text("I'm just always here.")
        }
    }
}

PlaygroundPage.current.setLiveView(ContentView())
Run Code Online (Sandbox Code Playgroud)

shu*_*ngb 4

据猜测,可能前一段时间就解决了这个问题,但是为了那些现在对 SwiftUI Form 之类的人敲头的人的好处(就像我一样:-))

事实证明,Forms、Lists 和(毫无疑问)其他组件故意忽略动画自定义,因为它们是“更高级别”的 SwiftUI View 组件(与 V 和 HStack 不同)。

他们这样做是因为 SwiftUI 的更高级别组件旨在传达语义信息并且(更实际地)在所有平台上都能正常工作。为了实现这一目标,苹果公司的工程决策是让动画变得“简单”,但(正如观察到的)仅限于本质上将其“打开”或“关闭”的程度。

它可能是这样设计的,因为如果开发人员想要更多的控制权。然后,苹果公司认为,鼓励他们使用较低级别的组件比尝试解决他们应用于较高级别视图组件的优化要更轻松。

无论如何,对于确定的人来说,通过将 View 包装在容器中并指定修饰符,至少有一个逃生口.animation(nil)(如Asperi 的 SO 答案中所述) 。

为了完整起见,下面显示了一个示例;就我个人而言,我避免使用这种模式,因为我怀疑它有点像手枪。

import PlaygroundSupport
import SwiftUI

struct ContentView: View {
    @State var showGoodAnimation = false
    @State var showBadAnimation = false

    var body: some View {
        Form {
            Toggle(isOn: self.$showGoodAnimation.animation(.easeInOut(duration: 1))) { Text("Yay!") }
            if self.showGoodAnimation {
                Text("I animate beautifully.")
            }
            Toggle(isOn: self.$showBadAnimation.animation()) { Text("Boo!") }
            VStack {
                if self.showBadAnimation {
                    List {
                        Text("I animated differently").padding()
                        Text("But am I a footgun?").padding()
                    }
                    .transition(.asymmetric(insertion: .slide, removal: .opacity))
                    .animation(.easeOut(duration: 5))
                }
            }
            .animation(nil)
            .transition(.slide)
            Text("I'm just always here.")
        }
    }
}

PlaygroundPage.current.setLiveView(ContentView())
Run Code Online (Sandbox Code Playgroud)