如何在SwiftUI中创建类似Notion的可展开切换列表?
SwiftUI实现类似Notion的可折叠Toggle列表
你当前使用List的children参数生成的是系统默认折叠列表,样式和交互逻辑和Notion的toggle list不符。要实现目标效果,需要自定义折叠状态管理和行样式,以下是修正后的代码:
struct Bookmark: Identifiable { let id = UUID() let name: String let icon: String var items: [Bookmark]? // 修正示例数据的引用错误 static let apple = Bookmark(name: "1", icon: "1.circle") static let bbc = Bookmark(name: "2", icon: "square.and.pencil") static let example1 = Bookmark(name: "September", icon: "star", items: [apple, bbc]) static let example2 = Bookmark(name: "2023", icon: "timer", items: [apple, bbc]) } struct ContentView: View { let items: [Bookmark] = [.example1, .example2] @State private var collapsedIds: Set<UUID> = [] // 记录分组的折叠状态 var body: some View { List { ForEach(items) { item in // 渲染分组行 BookmarkRow(item: item, isCollapsed: collapsedIds.contains(item.id)) { collapsedIds.toggle(item.id) // 切换折叠状态 } // 展开时渲染子项,添加缩进体现层级 if !collapsedIds.contains(item.id), let subItems = item.items { ForEach(subItems) { subItem in BookmarkRow(item: subItem, isCollapsed: false) {} .padding(.leading, 20) } } } } .listStyle(.plain) // 去除默认列表背景,贴近Notion简洁风格 } } // 自定义行视图,集成折叠按钮、图标和文字 struct BookmarkRow: View { let item: Bookmark let isCollapsed: Bool let onToggle: () -> Void var body: some View { Button(action: onToggle) { HStack(spacing: 8) { // 折叠/展开箭头 Image(systemName: isCollapsed ? "chevron.right" : "chevron.down") .font(.caption) .foregroundColor(.gray) // 自定义图标 Image(systemName: item.icon) Text(item.name) } .foregroundColor(.primary) } .buttonStyle(.plain) // 保留原生列表行的交互触感 } } // 扩展Set快速切换元素存在状态 extension Set where Element: Hashable { mutating func toggle(_ element: Element) { if contains(element) { remove(element) } else { insert(element) } } }
核心改动说明:
- 状态管理:用
@State private var collapsedIds记录每个分组的折叠状态,通过UUID唯一标识分组 - 自定义行视图:
BookmarkRow集成折叠箭头按钮,点击时触发状态切换,同时保留自定义图标和文字布局 - 层级缩进:子项添加
padding(.leading, 20)实现层级缩进,和Notion的列表层级一致 - 样式优化:使用
.listStyle(.plain)去除系统默认的分组背景,让列表更简洁 - 代码修正:修复原示例数据中错误的引用(
Bookmark.1改为Bookmark.apple)
内容的提问来源于stack exchange,提问作者Jojo Who
相关产品推荐
相关产品推荐

