当视图模型数据更改时,如何禁用动画?
我有以下代码:
struct FormView: View {
@ObservedObject var viewModel: FormViewModel
var body: some View {
List {
ForEach(viewModel.options) { option in
Text(option.displayValue)
}
}
}
}
每次更改视图模型List
时都会更新动画。
如何禁用它?
我尝试添加.animation(nil)
,但没有帮助
答案 0 :(得分:6)
我发现的解决方案是添加一个每次都会更改的唯一标识符,因此它将在没有动画的情况下每次都重新构建列表。在iOS 13.4上进行了验证。
var body: some View {
List {
ForEach(viewModel.options) { option in
Text(option.displayValue)
}
}
.id(UUID()) // no animation
}
答案 1 :(得分:1)
直到Apple给我们更改以在List上进行更改之前的解决方法是调用List.id(_ :) 它更改了List的内部状态,并强制List立即重新创建,而没有任何动画。有关详细信息,请参见List reload animation glitches
可以在任何View上执行相同的操作(func id()是View协议的一部分),但是您必须知道所有状态变量都将具有初始的“默认”状态,因此请谨慎使用。就像“重新创建”视图一样。
要了解其工作原理,请参见https://swiftui-lab.com/swiftui-id/
答案 2 :(得分:-1)
如果您不使用Section
,则无需在List内使用ForEach。所以代替:
List {
ForEach(viewModel.options) { option in
Text(option.displayValue)
})
}
以下代码足以编写:
List(viewModel.options) { option in
Text(option.displayValue)
}
而且更好地知道使用ForEach会产生一些问题,例如:SwiftUI: is it possible to use ForEach + ContextMenu?
如果仅使用ForEach()
或仅使用List()
+ .animation(nil)
,则必须解决您的问题:
示例1:
ForEach(viewModel.options) { option in
Text(option.displayValue)
}.animation(nil)
示例2:
List(viewModel.options) { option in
Text(option.displayValue)
}.animation(nil)
我已经在macOS 10.15.2(19C57)上进行了测试,并且运行良好。
您还可以尝试同时在.animation(nil)
和List
上使用ForEach
。我没有尝试...但是我认为这也会给您带来所需的效果。
List {
ForEach(viewModel.options) { option in
Text(option.displayValue)
}.animation(nil)
}.animation(nil)