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

SwiftUI:如何通过代码展开List中指定的带子项行?

代码控制SwiftUI可展开List的指定行展开

当然可以通过代码方式展开指定行,核心是利用SwiftUI List的expanded:绑定参数跟踪和控制展开状态,具体实现步骤如下:

  1. 给数据模型添加唯一标识符
    让你的数据模型遵循Identifiable协议(或自定义唯一id属性),确保能精准定位目标行:

    struct MyData: Identifiable {
        let id: UUID = UUID()
        let content: String
        var children: [MyData]?
    }
    
  2. 定义状态变量管理展开状态
    创建一个@State类型的集合,用来存储当前处于展开状态的行的id:

    @State private var expandedRows: Set<UUID> = []
    
  3. 绑定List的展开状态参数
    在List初始化时添加expanded:参数,将其与上面的状态变量绑定:

    List(myData, children: \.children, expanded: $expandedRows) { row in
        Text(row.content)
    }
    
  4. 代码触发指定行展开
    只要将目标行的id加入expandedRows集合,该行就会自动展开;移除id则会收起。示例场景:

    • 视图加载时自动展开第一行:
      .onAppear {
          if let firstRowId = myData.first?.id {
              expandedRows.insert(firstRowId)
          }
      }
      
    • 通过按钮手动触发展开指定行:
      .toolbar {
          Button("展开第二行") {
              expandedRows.insert(myData[1].id)
          }
      }
      

完整示例代码

struct ContentView: View {
    @State private var expandedRows: Set<UUID> = []
    
    let myData: [MyData] = [
        MyData(content: "父行1", children: [
            MyData(content: "子行1-1"),
            MyData(content: "子行1-2")
        ]),
        MyData(content: "父行2", children: [
            MyData(content: "子行2-1")
        ])
    ]
    
    var body: some View {
        List(myData, children: \.children, expanded: $expandedRows) { row in
            Text(row.content)
        }
        .onAppear {
            expandedRows.insert(myData.first!.id)
        }
        .toolbar {
            Button("展开父行2") {
                expandedRows.insert(myData[1].id)
            }
        }
    }
}

struct MyData: Identifiable {
    let id: UUID = UUID()
    let content: String
    var children: [MyData]?
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 18:50:45