LAZYVSTACK重新查看视图,防止删除后重新添加项目的适当动画

问题描述 投票:0回答:1
我有一个foreach我添加和删除项目,但是我正在遇到lazyvstack的动画问题。

LAZYVSTACK重复使用视图,因此,当我删除项目并在同一索引中添加新项目时,SwiftUi将其视为相同的视图,并且不播放插入动画。

为了强制动画,我更新了LazyvStack的ID(LazyID),但这会导致所有项目重新渲染,这效率低下。

我希望动画在添加/删除项目时可以正常工作,而无需触发现有视图的完整重新渲染。

根问题:

LazyvStack通过重复使用视图来优化渲染。 删除项目后,SwiftUI不会立即完全对其进行分解。 当将新项目插入相同的索引时,Swiftui重复了旧视图,跳过动画。


我需要什么:

使Swiftui识别出插入为真正的“新”项目的方法。 避免在LazyvStack上使用.ID(UUID())(迫使所有视图的重新呈现)。 防止LazyvStack在以前删除的索引中添加新项目时,以为它是重复使用旧视图的。


macos:[MacOS 15.2(24C101),Xcode 16.2]

enter image description here import SwiftUI struct ContentView: View { @State private var items: [ItemType] = [] @State private var lazyID: UUID = UUID() var body: some View { VStack { ScrollView { LazyVStack(spacing: 5.0) { ForEach(items) { item in CircleView(item: item) .transition( .asymmetric( insertion: .move(edge: .top), removal: .move(edge: .top) ) ) } } .id(lazyID) .animation(Animation.linear , value: items) } .padding() Spacer() HStack { Button("Append New Item") { let newItem = ItemType(value: items.count + 1) items.append(newItem) } Button("Remove last Item") { if let last = items.popLast() { print("Removed:", last.value) } else { print("Array is empty!") } // This will allow the animation to happen when adding a new item, but at the cost of re-rendering all views. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + DispatchTimeInterval.milliseconds(1000)) { // lazyID = UUID() } } } } .padding() } } struct CircleView: View, Equatable { let item: ItemType var body: some View { print("CircleView called for: " + String(describing: item.value)) return Circle() .fill(Color.red) .frame(width: 50.0, height: 50.0) .overlay(Circle().stroke(lineWidth: 1.0)) .overlay(Text("\(item.value)").foregroundStyle(.white)) } static func == (lhs: Self, rhs: Self) -> Bool { (lhs.item.id == rhs.item.id) } } struct ItemType: Identifiable, Equatable { let id: UUID = UUID() let value: Int static func == (lhs: Self, rhs: Self) -> Bool { (lhs.id == rhs.id) } }

swiftui,身份就是一切。在其数据模型中,Swiftui是一堆巨大的嵌套集合,需要扩散以检测身份变化并驱动动画。 当您这样做时:

struct ItemType: Identifiable, Equatable { let id: UUID = UUID() let value: Int }
您在每个实例上为同一的新身份创建一个新的身份。
swift macos swiftui
1个回答
0
投票
在哪里,您可能希望这两个结构相等,因为它们的值相同。 the the the thetheistity

,将一个与另一个区别于另一个区分开的东西

当您插入一项之后,例如,根据您的业务逻辑,它将始终为

value
。但是,您插入的
ItemType(value: 42) != ItemType(value: 42)

不等于以前可能存在的任何

ItemType
,因为

value

现在已经有了新的值。 每次您遇到某人时,您(可能)您(可能)也不会以新名称介绍自己。

总结,确定是什么使数据模型对象的每个实例与另一个实例不同,而不仅仅是楔入每个数据模型类型,以创建差异以触发swiftui绘图。
您修改的示例,使用

3

驱动

4

conformance4提供正确的动画。

4

请参阅

Https://developer.apple.com/videos/play/wwdc2021/10022/10022/100.
    

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.