4

这不是意味着可以控制在表单视图中发生的动画吗?我在这里有一个游乐场来演示这个问题,以及一个发生了什么的 gif。如您所见,我在第二个动画视图上的过渡完全被忽略了,我不得不手动放慢视频速度,因为持续时间也被忽略了。

我真的不想要缩放过渡,这只是为了证明无论我放什么动画都是一样的。这是预期的,还是一个错误?还是我只是在做完全错误的事情?

我也不清楚为什么 VStack 的动画与简单的 Text 字段的处理方式如此不同,后者很好地向下滑动,而 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())
4

1 回答 1

1

猜测一下,前段时间可能已经解决了这个问题,但是为了那些现在对 SwiftUI Form 之类的人大打出手的人的利益(就像我一样:-))

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

他们这样做是因为 SwiftUI 的高级组件旨在传达语义信息,并且(更实际地)在所有平台上都能很好地工作。为了实现这一点,Apple 的工程决策是让动画“简单”,但(如观察到的)只是在本质上将其“打开”或“关闭”的程度。

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

.animation(nil)无论如何,对于确定的情况,通过将视图包装在容器中并指定修饰符,至少有一个逃生舱口(如Asperi 的 SO 回答here中所述。

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

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())
于 2021-05-18T10:07:17.413 回答