ahe*_*eze 1 swift swiftui swiftui-foreach
我正在尝试向我的 中添加删除动画ForEach,以便其中的每个Card动画在删除时都会缩放。这是我到目前为止所拥有的:
问题是,无论Card按下哪一个,总是最后一个动画。有时,每张卡片内的文本都有奇怪的滑动/变形动画。这是我的代码:
/// Ran into this problem: "SwiftUI ForEach index out of range error when removing row"
/// `ObservableObject` solution from /sf/answers/4395723531/
class Card: ObservableObject, Identifiable {
let id = UUID()
@Published var name: String
init(name: String) {
self.name = name
}
}
struct ContentView: View {
@State var cards = [
Card(name: "Apple"),
Card(name: "Banana "),
Card(name: "Coupon"),
Card(name: "Dog"),
Card(name: "Eat")
]
var body: some View {
ScrollView(.horizontal) {
HStack {
ForEach(cards.indices, id: \.self) { index in
CardView(card: cards[index], removePressed: {
withAnimation(.easeOut) {
_ = cards.remove(at: index) /// remove the card
}
})
.transition(.scale)
}
}
}
}
}
struct CardView: View {
@ObservedObject var card: Card
var removePressed: (() -> Void)?
var body: some View {
Button(action: {
removePressed?() /// call the remove closure
}) {
VStack {
Text("Remove")
Text(card.name)
}
}
.foregroundColor(Color.white)
.font(.system(size: 24, weight: .medium))
.padding(40)
.background(Color.red)
}
}
Run Code Online (Sandbox Code Playgroud)
如何横向扩展Card被单击的而不是最后一个?
您看到此行为的原因是因为您使用索引作为idfor ForEach。因此,当从数组中删除一个元素时cards,看到的唯一区别ForEach是最后一个索引消失了。
您需要确保id唯一标识 的每个元素ForEach。
如果必须使用索引并标识每个元素,则可以同时使用该enumerated方法或zip数组及其索引。我喜欢后者:
ForEach(Array(zip(cards.indices, cards)), id: \.1) { (index, card) in
//...
}
Run Code Online (Sandbox Code Playgroud)
上面使用对象本身作为ID,这需要符合Hashable。如果你不想这样,你可以id直接使用该属性:
ForEach(Array(zip(cards.indices, cards)), id: \.1.id) { (index, card) in
//...
}
Run Code Online (Sandbox Code Playgroud)
为了完整起见,这是enumerated版本(从技术上讲,它不是索引,而是偏移量,但对于基于 0 的数组来说是相同的):
ForEach(Array(cards.enumerated()), id: \.1) { (index, card) in
//...
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1744 次 |
| 最近记录: |