view - 如何使用matchedGeometryEffect在SwiftUI中转换子视图?
问题描述
我有许多SwapItem
结构,每个都有一个 child SwapItemChild
。然后,使用ForEach
SwiftUI,我想显示每个的名称SwapItem
,称为项目视图,还包含一个与其各自颜色的圆圈SwapItemChild
,称为子视图。随后,我想交换两个项目的孩子,并让各自的孩子视图改变位置动画。这是受此广泛教程的其他示例的启发,但并非专门针对儿童视图交换。
matchedGeometryEffect
我尝试通过各自的 id 来识别每个子视图来做到这一点SwapItemChild
。然而,这会导致一个跳跃的动画,只有顶部的子视图向下移动,而底部的子视图会瞬间跳到顶部。
功能示例代码如下。
// MARK: - Model
struct SwapItem: Identifiable {
let id = UUID()
let name: String
var child: SwapItemChild
}
struct SwapItemChild: Identifiable {
let id = UUID()
let color: Color
}
class SwapItemStore: ObservableObject {
@Published private(set) var items = [SwapItem(name: "Task 1", child: SwapItemChild(color: .red)),
SwapItem(name: "Task 2", child: SwapItemChild(color: .orange))]
func swapOuterChildren(){
let tmpChild = items[0].child
items[0].child = items[1].child
items[1].child = tmpChild
}
}
// MARK: - View
struct SwapTestView: View {
@StateObject private var swapItemStore = SwapItemStore()
@Namespace private var SwapViewNS
var body: some View {
VStack(spacing: 50.0) {
Button(action: swapItemStore.swapOuterChildren){
Text("Swap outer children")
.font(.title)
}
VStack(spacing: 150.0) {
ForEach(swapItemStore.items){ item in
SwapTestItemView(item: item, ns: SwapViewNS)
}
}
}
}
}
struct SwapTestItemView: View {
let item: SwapItem
let ns: Namespace.ID
var body: some View {
HStack {
Circle()
.fill(item.child.color)
.frame(width: 100, height: 100)
.matchedGeometryEffect(id: item.child.id, in: ns)
.animation(.spring())
Text(item.name)
}
}
}
matchedGeometryEffect
让这些子视图无缝交换位置的正确实现是什么?
解决方案
我已经遇到过这种问题,试试这个:
ForEach(swapItemStore.items, id: \.self.child.id)
另一种方式 :
struct SwapItem: Identifiable, Hashable {
let id = UUID()
let name: String
var child: SwapItemChild
}
struct SwapItemChild: Identifiable, Hashable {
let id = UUID()
let color: Color
}
和 :
ForEach(swapItemStore.items, id: \.self)
请参阅:https ://www.hackingwithswift.com/books/ios-swiftui/why-does-self-work-for-foreach
推荐阅读
- postgresql - Postgres 时间:时区转换错误
- reactjs - 如果子元素为空,则隐藏整个父元素
- drupal-8 - 在 Drupal 安装中我遇到了很多错误,任何人都可以帮我缩短吗?
- postgresql - PostgreSQL - 在一台服务器上调整多个集群
- python-3.x - 发布请求 ServiceDesk+ API
- javascript - 从 Angular 上的数组中搜索过滤器
- mongodb - 如何使用 java 代码转换 mongodb 查询
- java - 如何从一张纸切换到所有其他纸并使用java在excel中获取它们的值
- jquery - 如何修复悬停时未显示禁用按钮的工具提示
- javascript - 获取 WooCommerce 购物车页面中添加到购物车的最后一项的产品 ID