You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI中ScrollView行swipeAction无法生效的解决方法咨询

SwiftUI ScrollView行侧滑删除失效的解决办法

你的问题出在用索引遍历ForEach,加上未正确实现swipeAction。索引作为id会在元素删除后导致SwiftUI无法正确识别行的唯一性,进而让侧滑功能失效。以下是修复后的完整代码:

import SwiftUI

struct TableItems: View {
    @State private var items: [Item] = [Item(id: UUID(), name: "", quantity: "", price: "", complete: "", shopName: "", isComplete: false)]
    @EnvironmentObject var tableModel: TableModel
    
    // 补充隐藏键盘的实现
    func hideKeyboard() {
        UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
    }
    
    var body: some View {
        VStack {
           HStack {
                Button(action: {
                    // 相机按钮逻辑
                }) {
                    Image(systemName: "camera")
                }
                .foregroundColor(.cartvoltDarkBlue)
                
                Spacer()
                
                Button {
                    hideKeyboard()
                } label: {
                    Image(systemName: "keyboard.chevron.compact.down")
                }
                .foregroundColor(.cartvoltDarkBlue)
                
                Spacer()

                Button(action: {
                    addRow()
                }) {
                    Image(systemName: "plus")
                }
                .foregroundColor(.cartvoltDarkBlue)
            }
           .padding()
            
            HStack {
                Text("Item")
                Spacer()
                Text("Quantity")
                Spacer()
                Text("Price")
                Spacer()
                Text("Store")
                Spacer()
                Image(systemName: "globe")
                    .foregroundColor(.black)
            }
            .padding(10)
            
            ScrollView {
                // 改用绑定数组遍历,利用Item的Identifiable特性保证行唯一性
                ForEach($items) { $item in
                    HStack {
                        HStack {
                            Button(action: {
                                // 直接通过绑定切换完成状态,无需手动查找索引
                                item.isComplete.toggle()
                            }) {
                                Image(systemName: item.isComplete ? "checkmark.circle" : "circle")
                            }
                            TextField("Enter item name", text: $item.name, onCommit: {
                                addRow()
                            })
                            Divider()
                            
                        }
                        TextField("Enter item quantity", text: $item.quantity, onCommit: {
                            addRow()
                        })
                        Divider()
                        TextField("Enter price", text: $item.price, onCommit: {
                            addRow()
                        })
                        Divider()
                        TextField("Enter store name", text: $item.shopName, onCommit: {
                            addRow()
                        })
                    }
                    .padding(.leading, 5)
                    .padding(.bottom, 10)
                    // 添加侧滑删除功能
                    .swipeAction(edge: .trailing, allowsFullSwipe: true) {
                        Button(role: .destructive) {
                            // 通过id定位元素并删除
                            if let index = items.firstIndex(where: { $0.id == item.id }) {
                                items.remove(at: index)
                            }
                        } label: {
                            Label("Delete", systemImage: "trash")
                        }
                    }
                }
            }
        }
    }

    func addRow() {
        items.append(Item(id: UUID(), name: "", quantity: "", price: "", complete: "", shopName: "", isComplete: false))
    }
}

struct Item: Identifiable {
    var id: UUID
    var name: String
    var quantity: String
    var price: String
    var complete: String
    var shopName: String
    var isComplete: Bool
}

// 补充自定义颜色的实现
extension Color {
    static let cartvoltDarkBlue = Color.blue // 替换为你的实际颜色值
}

// 补充TableModel的基础定义
class TableModel: ObservableObject {
    // 你的业务逻辑代码
}

关键修改点:

  • 遍历方式优化:将ForEach(0..<items.count, id: \.self)改为ForEach($items),直接绑定数组元素,借助Item的Identifiable特性确保每个行的唯一性,避免索引混乱导致的视图更新异常。
  • 侧滑功能实现:给每行外层HStack添加.swipeAction修饰符,通过元素唯一id定位并删除,保证删除逻辑的准确性。
  • 状态修改简化:完成状态切换直接通过绑定的$item修改,无需手动遍历数组查找索引,代码更简洁可靠。

内容的提问来源于stack exchange,提问作者Emere

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 07:35:11