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

SwiftUI中如何获取可展开List被点击项的层级索引路径

SwiftUI 多层级展开List获取点击项完整索引路径实现方案

核心思路

List(children:) 初始化方法不会在渲染闭包里自动传递当前项的层级索引,我们可以通过ID匹配+递归遍历的方式,从根菜单数组逐层查找目标项,累积记录每一层的索引,最终得到完整的层级路径。


具体实现步骤

1. 补全根菜单定义

你代码中引用的sampleMenuItems是顶层根数组,补全定义如下(和你现有的三级菜单结构匹配):

// 顶层根菜单数组
let sampleMenuItems = [
    MenuItem(name: "咖啡机", image: "espresso-machine", subMenuItems: espressoMachineMenuItems),
    MenuItem(name: "磨豆机", image: "grinder", subMenuItems: grinderMenuItems),
    MenuItem(name: "其他设备", image: "other", subMenuItems: otherMenuItems)
]

2. 实现递归索引路径查找方法

写一个通用递归方法,从根数组开始遍历,匹配菜单项的唯一id,逐层累积索引:

/// 递归查找目标菜单项的完整层级索引路径
/// - Parameters:
///   - menuItems: 当前遍历的菜单数组
///   - targetID: 目标菜单项的唯一ID
///   - currentPath: 递归过程中累积的路径,默认传空数组即可
/// - Returns: 完整索引路径数组(元素顺序对应从根到叶的每层索引),未找到返回nil
func findIndexPath(in menuItems: [MenuItem], targetID: UUID, currentPath: [Int] = []) -> [Int]? {
    for (index, item) in menuItems.enumerated() {
        let updatedPath = currentPath + [index]
        // 匹配到目标项直接返回路径
        if item.id == targetID {
            return updatedPath
        }
        // 存在子菜单则递归向下查找
        if let subMenu = item.subMenuItems, 
           let targetPath = findIndexPath(in: subMenu, targetID: targetID, currentPath: updatedPath) {
            return targetPath
        }
    }
    return nil
}

3. 修改点击回调获取路径

在原有onTapGesture回调中,传入当前点击项的id调用查找方法,即可拿到完整路径:

.onTapGesture {
    guard let indexPath = findIndexPath(in: sampleMenuItems, targetID: item.id) else { return }
    
    // 打印基础信息
    print("选中项名称:\(item.name)")
    print("索引路径数组:\(indexPath)") // 例:Leva S 对应输出 [0,0,1]
    
    // 拼接为你举例的代码访问路径格式
    var accessPath = "sampleMenuItems[\(indexPath[0])]"
    for idx in 1..<indexPath.count {
        accessPath += ".subMenuItems![\(indexPath[idx])]"
    }
    print("代码访问路径:\(accessPath)") // 例:Leva S 对应输出 sampleMenuItems[0].subMenuItems![0].subMenuItems![1]
    
    // 可直接通过索引路径从根数组取到目标项
    // var matchedItem = sampleMenuItems[indexPath[0]]
    // for idx in 1..<indexPath.count {
    //     matchedItem = matchedItem.subMenuItems![indexPath[idx]]
    // }
}

说明

  • 该方案支持任意层级的菜单嵌套,不局限于2-3级结构
  • 基于MenuItem的唯一UUID做匹配,即使不同层级存在同名菜单项也不会匹配错误
  • 拿到的indexPath数组可以直接和List的展开/选中逻辑绑定使用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 01:57:22