如何在 SwiftUI 中仅使用 ForEach 而不是列表来滑动删除

Nig*_*awk 8 swift swiftui

我正在 SwiftUI 中使用 ForEach 制作自定义列表。我的目标是进行滑动删除手势,而不是将 ForEach 嵌入到列表中。

到目前为止,这是我的代码:

import SwiftUI

struct ContentView: View {
let list = ["item1", "item2", "item3", "item4", "item5", "item6"]

var body: some View {
    VStack {
        List{
            
            ForEach(list, id: \.self) { item in
                Text(item)
                    .foregroundColor(.white)
                    .frame(maxWidth: .infinity)
                    .padding()
                    .background(Color.red)
                    .cornerRadius(20)
                    .padding()
                
            }
        }
    }
  }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
Run Code Online (Sandbox Code Playgroud)

我似乎找不到一种手势可以让我在不使用列表视图的情况下进行滑动删除。

我还想制作一个自定义删除按钮,当用户向左滑动项目时显示该按钮(如下图所示)。

在此输入图像描述

Ho *_*uan 4

这是我针对您的问题的解决方案。您应该为每一行添加DragGesture和创建offset。请记住,您的变量声明var不能被改变。你必须@State先添加。

struct ContentView: View {
    @State var list = ["item1", "item2", "item3", "item4", "item5", "item6"]
    @State private var offsets = [CGSize](repeating: CGSize.zero, count: 6)
    var body: some View {
        VStack {
            ForEach(list.indices, id: \.self) { index in
                
                HStack {
                Text(list[index])
                    .foregroundColor(.white)
                    .frame(maxWidth: .infinity)
                    .padding()
                    .background(Color.red)
                    .cornerRadius(20)
                    .padding()
                    
                    Button(action: {
                        self.list.remove(at: index)
                        self.offsets.remove(at: index)
                    }) {
                        Image(systemName: "xmark")
                    }
                }
                .padding(.trailing, -40)
                .offset(x: offsets[index].width)
                .gesture(
                    DragGesture()
                        .onChanged { gesture in
                            self.offsets[index] = gesture.translation
                            if offsets[index].width > 50 {
                                self.offsets[index] = .zero
                            }
                        }
                        .onEnded { _ in
                            if self.offsets[index].width < -100 {
                                self.list.remove(at: index)
                                self.offsets.remove(at: index)
                            }
                            else if self.offsets[index].width < -50 {
                                self.offsets[index].width = -50
                            }
                        }
                )
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)