如何在没有动画的情况下更新 SwiftUI 列表

fla*_*pys 12 ios swift swiftui

我想在没有任何插入动画的情况下更新 SwiftUI 列表。我List正在从一个@EnvironmentObject 我已经尝试将其List自身和包装PassthroughSubject.send()在一个withAnimation(.empty)块中的数据中获取它的数据,但这无济于事。

一个非常非常脏的解决方法是调用UIView.setAnimationsEnabled(false)(是的,UIKit 对 SwiftUI 有影响),但必须有一种类似于 SwiftUI 的方式来设置自定义插入动画。

Dog*_*fee 8

这有效,只需放在.id(UUID())列表的末尾

List {
    // for each etc
}.id(UUID())
Run Code Online (Sandbox Code Playgroud)

有点像 UIKit 的 reloadData


Gen*_*gan 7

虽然 DogCoffee 提供的答案有效,但它的效率很低。有时我们确实不得不通过低效来迫使系统做我们想做的事情。对于 SwiftUI 中的隐式动画,有一个更好的方法来禁用它们。

使用SwiftUI 中的事务机制,我们可以定义一个可以应用于任何视图的扩展。这将禁用视图和任何子项的动画。

对于列表视图示例,这避免了用新的但相同的副本替换列表中的所有数据。

extension View {
     
    func animationsDisabled() -> some View {
        return self.transaction { (tx: inout Transaction) in
            tx.disablesAnimations = true
            tx.animation = nil
        }.animation(nil)
    }
}
Run Code Online (Sandbox Code Playgroud)

尝试将此扩展应用到您的列表或包含视图的父级。您可能需要进行试验才能找到最理想的视图。

List {
    // for each etc
}.animationsDisabled()
Run Code Online (Sandbox Code Playgroud)


ryu*_*jin -4

.animate(nil)
Run Code Online (Sandbox Code Playgroud)

您可以在https://developer.apple.com/tutorials/swiftui/animating-views-and-transitions上找到更多信息

  • 我担心将 .animation(nil) 设置为 List 本身或其中的项目都会导致在加载新项目并将其更新到列表时“折叠”动画消失。 (2认同)