无法在表单中控制动画?
Not possible to control animations in a Form?
这不是意味着可以控制在窗体视图中发生的动画吗?我这里有一个演示问题的游乐场,以及发生的情况的 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())
我猜,可能前段时间解决了这个问题,但为了那些现在正在努力反对 SwiftUI Form 等的人的利益(就像我一样:-))
事实证明,表单、列表和(毫无疑问)其他组件故意忽略动画自定义,因为它们是“更高级别”的 SwiftUI 视图组件(与 V 和 HStack 不同)。
他们这样做是因为 SwiftUI 的高级组件旨在传达语义信息并且(更实际地)在所有平台上都能很好地工作。为实现这一目标,Apple 的工程决策一直是让动画变得“简单”,但(如观察到的那样)仅限于“打开”或“关闭”动画。
它很可能是这样设计的,因为如果开发人员想要更多的控制权。然后 Apple 相信鼓励他们使用较低级别的组件比尝试解决他们已应用于较高级别视图组件的优化要容易得多。
无论如何,对于确定的,通过将视图包装在容器中并指定 .animation(nil)
修饰符(如 .
中所述,至少有一个逃生口
为了完整起见,下面显示了一个示例;就个人而言,我避免使用这种模式,因为我怀疑它有点像步兵枪。
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())
这不是意味着可以控制在窗体视图中发生的动画吗?我这里有一个演示问题的游乐场,以及发生的情况的 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())
我猜,可能前段时间解决了这个问题,但为了那些现在正在努力反对 SwiftUI Form 等的人的利益(就像我一样:-))
事实证明,表单、列表和(毫无疑问)其他组件故意忽略动画自定义,因为它们是“更高级别”的 SwiftUI 视图组件(与 V 和 HStack 不同)。
他们这样做是因为 SwiftUI 的高级组件旨在传达语义信息并且(更实际地)在所有平台上都能很好地工作。为实现这一目标,Apple 的工程决策一直是让动画变得“简单”,但(如观察到的那样)仅限于“打开”或“关闭”动画。
它很可能是这样设计的,因为如果开发人员想要更多的控制权。然后 Apple 相信鼓励他们使用较低级别的组件比尝试解决他们已应用于较高级别视图组件的优化要容易得多。
无论如何,对于确定的,通过将视图包装在容器中并指定 .animation(nil)
修饰符(如
为了完整起见,下面显示了一个示例;就个人而言,我避免使用这种模式,因为我怀疑它有点像步兵枪。
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())