Search code examples
iosswiftswiftui

How to keep custom view background static while making swipe to delete action


So I have this code:

struct ContentView: View {
    @State private var names = ["Ted", "Barney", "Lily", "Robin", "Marshal"]

    var body: some View {
        List {
            ForEach(names, id: \.self) { name in
                ListRowView(name: name)
            }
            .onDelete(perform: deleteName)
        }
        .listStyle(.plain)
        .scrollContentBackground(.hidden)
    }

    func deleteName(at offsets: IndexSet) {
        names.remove(atOffsets: offsets)
    }
}

struct ListRowView: View {

    let name: String

    var body: some View {
        HStack {
            iconView
            titleView
            Spacer()
        }
        .background(
            RoundedRectangle(cornerRadius: 20)
                .fill(.purple)
        )
    }

    var titleView: some View {
        Text("\(name)")
            .foregroundStyle(.white)
    }


    var iconView: some View {
        Circle()
            .fill(Color.white.opacity(0.2))
            .frame(width: 80, height: 80)
            .padding()
    }
}

when I swipe to delete, it looks like this:

swipe to delete current look

but I am trying to achieve something like this:

desired look when swiped

I want the red view that appears from the right when swiping to be a part of the row background. I'm not sure how to explain it better. Perhaps I'm applying the background view in the wrong way?


Solution

  • You can achieve a very close design using the native APIs by a combination of the Section and insetGrouped style list:

    Demo

    List {
        ForEach(names, id: \.self) { name in
            Section { // 👈 Separate cells
                ListRowView(name: name)
            }
        }
        .onDelete(perform: deleteName)
        .listRowBackground(Color.purple) /// 👈 Use a simple background color
        .listRowInsets(.init()) // 👈 Fit the content to the edges of the cell
        .listSectionSpacing(16) // 👈 Nicer spacing
    }
    .listStyle(.insetGrouped) // 👈 Make the sections appear rounded
    .scrollContentBackground(.hidden)