SwiftUI中如何修改可折叠List的listRowBackground属性
SwiftUI 可折叠List自定义行背景实现方案
别信旧帖子说这个效果做不到,你关于给对应视图加.listRowBackground()的猜想方向完全正确,之前的方案无效是因为没有覆盖到层级列表所有行的原生背景层,也没清掉List组件自带的默认系统背景。
核心实现逻辑
用List(_:children:rowContent:)初始化的可折叠层级列表,所有行——不管是点了能展开/折叠的父组行,还是展开后显示的子行——都会走rowContent闭包生成视图,你直接给闭包里返回的行视图挂.listRowBackground()修饰符就行,所有行都会自动应用这个配置,根本不需要单独给Bookmark.items对应的子节点拆特殊视图逻辑。
可直接运行的示例代码
struct Bookmark: Identifiable { let id = UUID() let name: String let icon: String var items: [Bookmark]? // 测试用示例数据 static let apple = Bookmark(name: "Apple", icon: "1.circle") static let bbc = Bookmark(name: "BBC", icon: "square.and.pencil") static let swift = Bookmark(name: "Swift", icon: "bolt.fill") static let twitter = Bookmark(name: "Twitter", icon: "mic") static let example1 = Bookmark(name: "Favorites", icon: "star", items: [Bookmark.apple, Bookmark.bbc, Bookmark.swift, Bookmark.twitter]) static let example2 = Bookmark(name: "Recent", icon: "timer", items: [Bookmark.apple, Bookmark.bbc, Bookmark.swift, Bookmark.twitter]) static let example3 = Bookmark(name: "Recommended", icon: "hand.thumbsup", items: [Bookmark.apple, Bookmark.bbc, Bookmark.swift, Bookmark.twitter]) } struct ContentView: View { let items: [Bookmark] = [.example1, .example2, .example3] init() { // 兼容iOS15及以下版本,清掉List默认的系统背景 UITableView.appearance().backgroundColor = .clear } var body: some View { List(items, children: \.items) { row in HStack { Image(systemName: row.icon) Text(row.name) } // 自定义行背景的核心代码 .listRowBackground( // 靠判断items是否为nil就能区分父行和子行,分别设不同背景 row.items != nil ? Color.blue.opacity(0.1) : Color.clear // 要全透明背景直接传Color.clear就行 ) } // iOS16+必须加这行,把系统默认的滚动内容背景藏掉 .scrollContentBackground(.hidden) // 这里可以给整个List设你要的整体背景 .background(Color(uiColor: .systemGroupedBackground)) } }
常见踩坑说明
- 别把
.listRowBackground()修饰符加在List外面,必须放在rowContent闭包返回的行视图上,加在外层完全不会生效 - 之前的老方案没用,本质是只改了List的整体背景,没处理每一行自带的默认白底/系统灰底,这些行背景会把你设的列表整体背景挡住,看起来就像改了没效果
- 要给父行、子行设不同样式根本不用拆视图,在闭包里判断当前节点的
items有没有值就行:非空就是可折叠的父组行,空的就是最末层的子行,对应返回不同配置就好
内容的提问来源于stack exchange,提问作者Sylar
相关产品推荐
相关产品推荐

