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

SwiftUI侧滑删除时如何使自定义行背景与删除区域融合

SwiftUI 侧滑删除背景融合问题解决

我编写了如下SwiftUI代码实现列表侧滑删除功能:

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()
    }
}

当前侧滑删除时的效果:
当前侧滑删除效果

期望实现的效果:
期望的侧滑删除效果

我希望侧滑时右侧出现的红色删除区域能够成为行背景的一部分,怀疑是背景视图的设置方式有误,请问该如何解决?


解决方案

问题核心在于你把背景应用在了HStack上,而非列表行的容器层级。SwiftUI的列表行默认会将滑动操作区域与行内容分开渲染,要让删除区域和行背景融合,需将背景设置到列表行层级。

修改步骤:

  1. 移除ListRowView中HStack的.background修饰符
  2. 在ContentView里给ListRowView添加.listRowBackground,把紫色圆角背景放在这里

修改后的完整代码:

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)
                    .listRowBackground(
                        RoundedRectangle(cornerRadius: 20)
                            .fill(.purple)
                    )
            }
            .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()
        }
    }

    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()
    }
}

说明

  • .listRowBackground是SwiftUI专门用于设置列表行背景的修饰符,它会作用于整个行的布局空间,包括滑动操作时的删除区域。
  • 原代码中HStack.background仅作用于内容区域,导致滑动时删除区域显示默认背景,与行内容背景分离。
  • 修改后紫色圆角背景会覆盖整个行,侧滑时红色删除按钮会叠加在该背景上,实现你想要的融合效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 00:37:44