SwiftUI中观察到的对象更改时如何禁用列表中的动画?

时间:2019-11-23 23:23:21

标签: ios swiftui

当视图模型数据更改时,如何禁用动画?

我有以下代码:

struct FormView: View {

    @ObservedObject var viewModel: FormViewModel

    var body: some View {
        List {
            ForEach(viewModel.options) { option in
                Text(option.displayValue)
            }
        }
    }
}

每次更改视图模型List时都会更新动画。
如何禁用它?
我尝试添加.animation(nil),但没有帮助

3 个答案:

答案 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)

  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?

  2. 如果仅使用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)上进行了测试,并且运行良好。

  3. 您还可以尝试同时在.animation(nil)List上使用ForEach。我没有尝试...但是我认为这也会给您带来所需的效果。

    List {
        ForEach(viewModel.options) { option in
            Text(option.displayValue)
        }.animation(nil)
    }.animation(nil)