我想更新SwiftUI列表而不使用任何插入动画。我的List正在从@EnvironmentObject获取数据,我已经尝试将List本身和PassthroughSubject.send() Package 在withAnimation(.empty)块中,但这没有帮助。一个非常非常脏的解决方法是调用UIView.setAnimationsEnabled(false)(是的,UIKit对SwiftUI有影响),但必须有一个类似SwiftUI的方法来设置自定义插入动画。
List
@EnvironmentObject
PassthroughSubject.send()
withAnimation(.empty)
UIView.setAnimationsEnabled(false)
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()
yvfmudvl2#
这是可行的,只需将.id(UUID())放在列表的末尾即可
.id(UUID())
List { // for each etc }.id(UUID())
类似于reloadData for UIKit
g6ll5ycj3#
在tvOS上,这对我来说很有用:
List { ... } .animation(.none)
vdgimpew4#
Swift 5.8:
.animation()仍然适用于 * 一些 * 原生SwiftUI视图,如Text(),Image()等,并且不会被弃用。如果您尝试在自定义视图上使用它,则会被弃用。您可以切换到withAnimation或animation(_:value:),但也可以使自定义SwiftUI视图符合Equatable。
.animation()
withAnimation
animation(_:value:)
Equatable
struct CustomView: View, Equatable { var body: some View { } }
ao218c7q5#
.animate(nil)
您可以在https://developer.apple.com/tutorials/swiftui/animating-views-and-transitions上找到更多信息
5条答案
按热度按时间mpgws1up1#
虽然DogCoffee提供的答案有效,但它的效率很低。有时我们确实必须通过效率低下来迫使系统做我们想做的事情。在SwiftUI中使用隐式动画的情况下,有一种更好的方法可以禁用它们。
使用SwiftUI中的Transaction机制,我们可以定义一个可以应用于任何视图的扩展。这将禁用视图和任何子视图的动画。
对于列表视图示例,这避免了用新的但相同的副本替换列表中的所有数据。
尝试将此扩展应用于列表或包含视图的父视图。您可能需要进行试验以找到理想的视图。
yvfmudvl2#
这是可行的,只需将
.id(UUID())
放在列表的末尾即可类似于reloadData for UIKit
g6ll5ycj3#
在tvOS上,这对我来说很有用:
vdgimpew4#
Swift 5.8:
.animation()
仍然适用于 * 一些 * 原生SwiftUI视图,如Text(),Image()等,并且不会被弃用。如果您尝试在自定义视图上使用它,则会被弃用。您可以切换到
withAnimation
或animation(_:value:)
,但也可以使自定义SwiftUI视图符合Equatable
。ao218c7q5#
您可以在https://developer.apple.com/tutorials/swiftui/animating-views-and-transitions上找到更多信息