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

fsi0uk1n  于 2023-04-10  发布在  Swift
关注(0)|答案(5)|浏览(135)

我想更新SwiftUI列表而不使用任何插入动画。我的List正在从@EnvironmentObject获取数据,我已经尝试将List本身和PassthroughSubject.send() Package 在withAnimation(.empty)块中,但这没有帮助。
一个非常非常脏的解决方法是调用UIView.setAnimationsEnabled(false)(是的,UIKit对SwiftUI有影响),但必须有一个类似SwiftUI的方法来设置自定义插入动画。

mpgws1up

mpgws1up1#

虽然DogCoffee提供的答案有效,但它的效率很低。有时我们确实必须通过效率低下来迫使系统做我们想做的事情。在SwiftUI中使用隐式动画的情况下,有一种更好的方法可以禁用它们。
使用SwiftUI中的Transaction机制,我们可以定义一个可以应用于任何视图的扩展。这将禁用视图和任何子视图的动画。
对于列表视图示例,这避免了用新的但相同的副本替换列表中的所有数据。

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

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

List {
    // for each etc
}.animationsDisabled()
yvfmudvl

yvfmudvl2#

这是可行的,只需将.id(UUID())放在列表的末尾即可

List {
    // for each etc
}.id(UUID())

类似于reloadData for UIKit

g6ll5ycj

g6ll5ycj3#

在tvOS上,这对我来说很有用:

List {
    ...
}
    .animation(.none)
vdgimpew

vdgimpew4#

Swift 5.8:

.animation()仍然适用于 * 一些 * 原生SwiftUI视图,如Text(),Image()等,并且不会被弃用。如果您尝试在自定义视图上使用它,则会被弃用。
您可以切换到withAnimationanimation(_:value:),但也可以使自定义SwiftUI视图符合Equatable

struct CustomView: View, Equatable {
    var body: some View {

    }
}

相关问题