SwiftUI macOS 12 中如何调整List内空单元格占位符的尺寸
你遇到的现象不是Bug,\.defaultMinListRowHeight 环境变量仅对有对应数据项的列表行生效,空单元格占位符的高度由List底层视图的默认行高控制,二者属于独立配置项。
你提供的效果示意图如下:
以下是两种可实现Finder一致样式的解决方案:
方案1:手动补空白占位项(全版本兼容,效果最贴合Finder)
这种方法可以1:1匹配Finder的空行表现,原生的交替背景、分隔线、选择逻辑都不会受影响,实现思路是根据你需要的列表显示行数,在数据源不足时补充空白占位项:
// 可根据List实际可用高度动态计算最少展示行数,这里以一屏至少展示15行为例 let minDisplayRows = 15 let displayItems = items + Array(repeating: nil, count: max(0, minDisplayRows - items.count)) List(displayItems, selection: $selection) { item in if let item = item { ListCellView(description: item.description, date: item.date) } else { // 空白占位行高度和实际行保持一致 Color.clear .frame(height: 58) // 保持分隔线和实际行样式一致 .listRowSeparator(.visible) } } .listStyle(.inset(alternatesRowBackgrounds: true)) .environment(\.defaultMinListRowHeight, 58)
方案2:修改底层NSTableView配置(仅macOS适用,无需修改数据源)
如果不想改动原有数据源逻辑,可以通过桥接AppKit修改List底层NSTableView的全局行高配置,会同时作用于实际行和空占位行:
extension View { func listAllRowHeight(_ height: CGFloat) -> some View { onAppear { func findTableView(in view: NSView) -> NSTableView? { if let tableView = view as? NSTableView { return tableView } for subview in view.subviews { if let result = findTableView(in: subview) { return result } } return nil } guard let rootView = NSApplication.shared.keyWindow?.contentView else { return } findTableView(in: rootView)?.rowHeight = height } } }
使用时直接在原有List链式调用后添加Modifier即可:
List(items, selection: $selection) { item in ListCellView(description: item.description, date: item.date) } .listStyle(.inset(alternatesRowBackgrounds: true)) .environment(\.defaultMinListRowHeight, 58) .listAllRowHeight(58) // 新增这行即可
两种方案都可以完美匹配你需要的Finder样式,空行高度、交替背景、分隔线都会和实际行保持一致。
内容的提问来源于stack exchange,提问作者Roman Banks
相关产品推荐
相关产品推荐


