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

如何在SwiftUI中创建父子元素类型不同的层级侧边栏?

SwiftUI实现支持不同类型元素的可选中层级侧边栏

完全可以用SwiftUI实现,不需要依赖AppKit。核心思路是通过统一枚举类型封装不同的数据源模型,结合DisclosureGroup实现层级折叠,同时处理选中状态。

步骤1:定义统一的侧边栏元素枚举

用枚举包裹MailServer和MailServerFolder,让它们统一遵循Identifiable协议,方便List统一处理:

enum SidebarItem: Identifiable {
    case server(MailServer)
    case folder(MailServerFolder)
    
    var id: UUID {
        switch self {
        case .server(let server): return server.id
        case .folder(let folder): return folder.id
        }
    }
    
    var name: String {
        switch self {
        case .server(let server): return server.name
        case .folder(let folder): return folder.name
        }
    }
}

步骤2:改造视图实现层级与选中逻辑

利用DisclosureGroup构建层级结构,通过List(selection:)绑定选中状态,自定义行视图区分父/子元素样式:

struct TestView: View {
    let servers: [MailServer]
    @State private var selectedItemId: UUID?
    
    var body: some View {
        List(selection: $selectedItemId) {
            ForEach(servers) { server in
                // 父元素:带折叠功能的DisclosureGroup,label设为可选中的行
                DisclosureGroup {
                    // 子元素:遍历服务器下的文件夹
                    ForEach(server.folders) { folder in
                        SidebarRow(item: .folder(folder), isSelected: selectedItemId == folder.id)
                            .tag(folder.id)
                    }
                } label: {
                    SidebarRow(item: .server(server), isSelected: selectedItemId == server.id)
                        .tag(server.id)
                }
            }
        }
        .listStyle(.sidebar) // 适配macOS侧边栏默认样式
    }
}

// 自定义侧边栏行视图,区分父/子元素样式与选中状态
struct SidebarRow: View {
    let item: SidebarItem
    let isSelected: Bool
    
    var body: some View {
        HStack {
            Text(item.name)
        }
        .foregroundColor(isSelected ? .accentColor : .primary)
        .font(item is .server ? .headline : .body) // 父元素用更醒目字体
        .padding(.vertical, 4)
    }
}

关键说明

  • 枚举SidebarItem解决了不同类型数据源无法直接在List中混用的问题,同时保留了原模型的类型信息。
  • DisclosureGroup原生支持层级折叠,完全匹配macOS邮件侧边栏的交互逻辑。
  • 通过List(selection:)和tag()实现选中状态的绑定,父/子元素都能被独立选中。
  • 自定义SidebarRow可以灵活调整样式,比如父元素加粗、选中时高亮等,贴合需求。

内容的提问来源于stack exchange,提问作者Alex S. Glomsaas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 10:10:19