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

SwiftUI列表侧滑操作如何适配圆角样式?

解决SwiftUI Plain List侧滑操作适配圆角的问题

在使用Plain样式的SwiftUI List时,若为列表行添加了圆角边框,默认的侧滑操作(swipeActions)不会自动适配圆角,导致视觉不一致。以下方案无需更换列表样式,即可实现类似天气App的圆角侧滑效果:

核心思路

问题根源在于默认列表行的底层背景是直角矩形,侧滑时会露出该背景,同时侧滑按钮本身也未设置圆角。我们需要:

  1. 替换列表行的底层背景为带圆角和边框的形状
  2. 给侧滑按钮添加匹配的圆角,并对齐行的内边距

修改后的代码

struct CustomList: View {
    var body: some View {
        List {
            ForEach(state.sections) { section in
                inboxSection(section: section)
            }
        }
        .listStyle(.plain)
    }

    private func inboxSection(section: Section) -> some View {
        Section(header: sectionHeader(for: section)) {
            ForEach(section.elements) { element in
                ItemRow(element: element)
                    .swipeActions(edge: .leading, allowsFullSwipe: false) {
                        CustomButton()
                            .cornerRadius(.BorderRadius.lg)
                            .padding(.vertical, 4) // 匹配行的上下内边距
                    }
                    .listRowInsets(EdgeInsets(top: 4, leading: 0, bottom: 4, trailing: 0))
                    .listRowSeparator(.hidden)
                    // 用listRowBackground替换原有的roundedCornerWithBorder,覆盖整个行背景
                    .listRowBackground(
                        RoundedRectangle(cornerRadius: .BorderRadius.lg)
                            .fill(Color.white) // 替换为你的行背景色
                            .overlay(
                                RoundedRectangle(cornerRadius: .BorderRadius.lg)
                                    .stroke(Color.Light.Border.defaultColor, lineWidth: 1)
                            )
                    )
            }
        }
    }

    @ViewBuilder
    private func sectionHeader(for section: ViewState.Section) -> some View {
        Text(section.headerTitle)
    }
}

// 保留原有的RoundedCorner形状和View扩展(若ItemRow内部需要单独设置圆角可继续使用)
struct RoundedCorner: Shape {
    var radius: CGFloat = .infinity
    var corners: UIRectCorner = .allCorners

    func path(in rect: CGRect) -> Path {
        let path = UIBezierPath(
            roundedRect: rect,
            byRoundingCorners: corners,
            cornerRadii: CGSize(width: radius, height: radius)
        )
        return Path(path.cgPath)
    }
}

public extension View {
    func cornerRadius(_ radius: CGFloat, corners: UIRectCorner) -> some View {
        clipShape(RoundedCorner(radius: radius, corners: corners))
    }

    func roundedCornerWithBorder(
        lineWidth: CGFloat = 1,
        borderColor: Color,
        radius: CGFloat,
        corners: UIRectCorner
    ) -> some View {
        clipShape(RoundedCorner(radius: radius, corners: corners))
            .overlay(RoundedCorner(radius: radius, corners: corners)
                .stroke(borderColor, lineWidth: lineWidth))
    }
}

关键说明

  • 替换行背景:使用listRowBackground设置整个行的背景为带圆角和边框的矩形,替代原有的roundedCornerWithBorder修饰(原修饰仅作用于ItemRow内容,无法覆盖行的底层背景)。
  • 适配侧滑按钮:给swipeActions内的按钮添加cornerRadius,并通过padding(.vertical, 4)匹配行的上下内边距,确保按钮圆角与行圆角对齐,视觉统一。
  • ItemRow适配:若ItemRow自身有背景色,需确保其与listRowBackground的背景色一致,或设置ItemRow背景为透明,避免样式冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 16:13:16