记录一次树形分级列表的实现

栏目: IOS · 发布时间: 5年前

内容简介:项目需求需要对用户根据推荐人的不同进行树形结构显示.使用 tableView 实现这一需求.使用 tableView 实现先树形结构(不同的 cell 样式显示不同的等级),当点击 cell 时,判断当前点击的 cell 是否存在下一级,是否已经是打开状态.如果存在下一级,关闭状态,则通过插入 cell 实现点击展开树形图的效果.如果存在下一级且已经展开则通过删除 cell的方式实现树形图的关闭效果.

项目需求需要对用户根据推荐人的不同进行树形结构显示.使用 tableView 实现这一需求.

实现思路

使用 tableView 实现先树形结构(不同的 cell 样式显示不同的等级),当点击 cell 时,判断当前点击的 cell 是否存在下一级,是否已经是打开状态.如果存在下一级,关闭状态,则通过插入 cell 实现点击展开树形图的效果.如果存在下一级且已经展开则通过删除 cell的方式实现树形图的关闭效果.

具体实现

  1. 定义数据结构类型,如下:
class YTTTreeListModel: NSObject {
    
    /**
        你所需要的属性
        var name: String = ""
        var address: String = ""
        var age: Int = -1
        ...
    **/
    
    // 当前节点是否有下一级
    var isShow: Bool = false
    // 当前节点是否展开
    var isOpen: Bool = false
    // 当前的等级
    var level: Int = 0
    // 当前节点的子节点
    var child: [QWMyTeamModel] = []
}
复制代码
  1. 定义主要的方法(递归算法)
/// 获取 cell 的行数
///
/// - Parameter items: 数据源
/// - Returns: cell 行数
private func getRowsNum(_ items: [YTTTreeListModel]) -> Int {
    var num = 0
    items.forEach { (model) in
        num += 1
        if model.isShow && model.isOpen && model.child.count > 0 {
            num += getRowsNum(model.child)
        }
    }
    return num
}

/// 获取当前 cell 的数据模型
///
/// - Parameters:
///   - items: 数据源
///   - index: 当前位置
/// - Returns: 数据模型
private func getItem(_ items: [YTTTreeListModel], index: inout Int) -> YTTTreeListModel? {

    for item in items {
        if index == 0 {
            return item
        }
        index -= 1
        if item.isShow && item.isOpen && item.child.count > 0 {
            if let model = getItem(item.child, index: &index) {
                return model
            }
        }
    }
    return nil
}

/// 获取需要添加或删除的 cell
///
/// - Parameters:
///   - item: 当前数据模型(点击的 cell)
///   - index: 当前位置
/// - Returns: 需要删除或添加位置
private func getIndexPath(_ item: YTTTreeListModel, index: inout Int) -> [IndexPath] {
    var indexPaths: [IndexPath] = []
    for item in item.child {
        index += 1
        indexPaths.append(IndexPath(row: index, section: 0))
        if item.isShow && item.isOpen && item.child.count > 0 {
            indexPaths.append(contentsOf: getIndexPath(item, index: &index))
        }
    }
    return indexPaths
}
复制代码
  1. 实现代理方法
// dataArr     private var dataArr: [YTTTreeListModel] = []

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return getRowsNum(dataArr) 
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    var index = indexPath.row
    if let model = getItem(dataArr, index: &index) {
        if model.level == 1 {
            // 返回第一级样式
        } else if model.level == 2 {
            // 返回第二级样式
        }else if model.level == 3 {
            // 返回第三级样式
        }
        ...
    }
    return UITableViewCell()
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    var index = indexPath.row
    if let model = getItem(dataArr, index: &index) {

        if model.isOpen {
            tableView.beginUpdates()
            model.isOpen = false
            var ind = indexPath.row
            tableView.reloadRows(at: [indexPath], with: .none)
            tableView.deleteRows(at: getIndexPath(model, index: &ind), with: .none)
            tableView.endUpdates()
        }else {
            if !model.isShow {
                return
            }
            
            // 存在下一级且子级已经加载直接展开
            if model.isShow == 1 && model.child.count > 0 {
                tableView.beginUpdates()
                model.isOpen = true
                var ind = indexPath.row
                tableView.reloadRows(at: [indexPath], with: .none)
                tableView.insertRows(at: getIndexPath(model, index: &ind), with: .none)
                tableView.endUpdates()
            }else {
            // 存在下一级,但数据未请 求网络请求
            http.globalPOST(url: **, parameters: ["": ""], success: { [weak self] (result) in
                if let models = YTTTreeListModel(dictArray: result) as? [YTTTreeListModel] {
                    model.child = models.compactMap({ (item) -> YTTTreeListModel in
                        item.level = model.level + 1 // 设置等级
                        return item
                    })
                    tableView.beginUpdates()
                    model.isOpen = true
                    var ind = indexPath.row
                    tableView.reloadRows(at: [indexPath], with: .none)
                    if let indexs = self?.getIndexPath(model, index: &ind) {
                        tableView.insertRows(at: indexs, with: .none)
                    }
                    tableView.endUpdates()
                }

            }, fail: {(error) in

            }, isHUD: true)
            }
        }
    }
}
复制代码

以上所述就是小编给大家介绍的《记录一次树形分级列表的实现》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

微创新

微创新

德鲁•博迪、雅各布•戈登堡 / 钟莉婷 / 中信出版社 / 2014-4-5 / 42.00

好产品不一定要颠覆,微小改进就能让用户尖叫! 引爆创新领域的全新方法论 互联网时代行之有效的5大创新策略 创业者、产品经理必读的创新行动指南 《怪诞行为学》作者 丹•艾瑞里 《影响力》作者 罗伯特•西奥迪尼 全球50位最具影响力的商业思想家之一丹尼尔•平克 周鸿祎、黎万强、罗振宇、牛文文、张鹏 联袂重磅推荐 为什么iPod可以在众多mp3产品中......一起来看看 《微创新》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具