記錄一次樹形分級列表的實現

項目需求須要對用戶根據推薦人的不一樣進行樹形結構顯示.使用 tableView 實現這一需求.算法

實現思路

使用 tableView 實現先樹形結構(不一樣的 cell 樣式顯示不一樣的等級),當點擊 cell 時,判斷當前點擊的 cell 是否存在下一級,是否已是打開狀態.若是存在下一級,關閉狀態,則經過插入 cell 實現點擊展開樹形圖的效果.若是存在下一級且已經展開則經過刪除 cell的方式實現樹形圖的關閉效果.swift

具體實現

  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)
            }
        }
    }
}
複製代碼
相關文章
相關標籤/搜索