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

栏目: 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)
            }
        }
    }
}
复制代码

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

查看所有标签

猜你喜欢:

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

自己动手做iOS App

自己动手做iOS App

张子怡 / 电子工业出版社 / 2017-8 / 69.00

《自己动手做iOS App:从设计开发到上架App Store》为想要接触iOS 应用设计、开发的读者提供了由浅入深的详细指导。从iOS 应用制作的步骤是什么,应该使用什么软件,如何发布应用到App Store,到iOS 的设计理念是什么,如何正确书写Swift 语言,再到后端和客户端是如何交互运作的等,本书配合图示,精辟、直观地阐明了iOS 应用制作中的种种疑问。 如果你是一位第一次接触i......一起来看看 《自己动手做iOS App》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

在线进制转换器
在线进制转换器

各进制数互转换器

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具