// // IHPermissionView.swift // Inhealth // // Created by weclouds on 2019/12/19. // Copyright © 2019 weclouds. All rights reserved. // import UIKit protocol IHTreeTableViewDelegate:NSObjectProtocol { func treeCellClick(node:IHTreeTableViewNode,indexPath:IndexPath) } class IHPermissionView: UIView { fileprivate let hotelID = "HotelCell" fileprivate let buildID = "buildCell" fileprivate let floodID = "floodCell" weak var treeDelegate:IHTreeTableViewDelegate? //外部传入的数据元(根节点集合) var rootNodes: [IHTreeTableViewNode] = [IHTreeTableViewNode](){ didSet{ getExpandNodeArray() self.tableView.reloadData() } } ///内部使用的数据源 fileprivate var tempNodeArray : [IHTreeTableViewNode] = [IHTreeTableViewNode]() ///点击“展开”,添加的字节点的索引数组 fileprivate var insertIndexPaths:[IndexPath] = [IndexPath]() private var insertRow = 0 ///点击“收缩”,删除的子节点的“索引数组” fileprivate var deleteIndexPaths : [IndexPath] = [IndexPath]() lazy var tableView : UITableView = { let tableView = UITableView(frame: CGRect.zero, style: .plain) tableView.separatorStyle = .none tableView.backgroundColor = .white tableView.delegate = self tableView.dataSource = self tableView.register(UINib(nibName: "IHPermissionHeaderCell", bundle: nil), forCellReuseIdentifier: hotelID) tableView.register(UINib(nibName: "IHSecondaryCell", bundle: nil), forCellReuseIdentifier: buildID ) tableView.register(UINib(nibName: "IHThirdGradeCell", bundle: nil), forCellReuseIdentifier: floodID) return tableView }() override init(frame: CGRect) { super.init(frame: frame) addSubview(tableView) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func layoutSubviews() { super.layoutSubviews() self.tableView.frame = self.bounds } /// 添加本节点及展开的子节点(包括展开的孙子节点)至数组中 /// - Parameters /// - mode : 本节点 func addExpandNodeToArray(node:IHTreeTableViewNode) { tempNodeArray.append(node) if node.isExpand { // 当前节点展开,添加其子节点 for child in node.subNodes { addExpandNodeToArray(node: child) } } } ///获取所有展开的节点数组 private func getExpandNodeArray(){ for rootNode in rootNodes { if rootNode.perentNode == nil { //再次判断是否是根节点 addExpandNodeToArray(node: rootNode) } } } ///是否是叶子结点 /// /// - Parameter node :节点 /// - Retures : ture - 是 ; false - 否 fileprivate func isLeafNode(node:IHTreeTableViewNode)->Bool{ return node.subNodes.count == 0 } /// 点击”展开“,添加子节点(如果子节点也处于展开状态,添加子节点) /// /// - Parameter node :节点 fileprivate func insertChildNode(node:IHTreeTableViewNode){ node.isExpand = true if node.subNodes.count == 0 { return } insertRow = tempNodeArray.index(of: node)! + 1 for childNode in node.subNodes { let childRow = insertRow let childIndexPath = IndexPath(row: childRow, section: 0) insertIndexPaths.append(childIndexPath) tempNodeArray.insert(childNode, at: childRow) insertRow += 1 if childNode.isExpand { insertChildNode(node: childNode) } } } ///点击“收缩”,删除所有处于展开转台饿子节点索引 /// - Parameter node :节点 fileprivate func getDeleteIndexPaths(node:IHTreeTableViewNode){ if node.isExpand {//再次确认节点处于展开状态 for childNode in node.subNodes { let childRow = tempNodeArray.index(of: childNode)! let childIndexPath = IndexPath(row: childRow, section: 0) deleteIndexPaths.append(childIndexPath) if childNode.isExpand { getDeleteIndexPaths(node: childNode) } } } } /// 点击“收缩”,删除所有处于展开状态的子节点 /// /// -Parameter node 节点 fileprivate func deleteChildNode(node:IHTreeTableViewNode){ getDeleteIndexPaths(node: node) node.isExpand = false for _ in deleteIndexPaths { tempNodeArray.remove(at: deleteIndexPaths.first!.row) } } } extension IHPermissionView:UITableViewDelegate,UITableViewDataSource{ func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return tempNodeArray.count } func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { return 0.01 } func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat { return 0.01 } func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { let node = tempNodeArray[indexPath.row] if node.depth == 0{ return 65 }else if node.depth == 1{ return 50 }else{ return 40 } } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let node = tempNodeArray[indexPath.row] let isLeaf = isLeafNode(node: node) if node.depth == 0{ let cell = tableView.dequeueReusableCell(withIdentifier: hotelID) as! IHPermissionHeaderCell cell.selectionStyle = .none cell.isLeaf = isLeaf cell.node = node return cell }else if node.depth == 1{ let cell = tableView.dequeueReusableCell(withIdentifier: buildID) as! IHSecondaryCell cell.selectionStyle = .none cell.isLeaf = isLeaf cell.node = node return cell }else{ let cell = tableView.dequeueReusableCell(withIdentifier: floodID) as! IHThirdGradeCell cell.selectionStyle = .none cell.isLeaf = isLeaf cell.node = node return cell } return UITableViewCell() } func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let node = tempNodeArray[indexPath.row] if node.depth == 0{ let cell = tableView.cellForRow(at: indexPath) as! IHPermissionHeaderCell cell.isExpand = node.isExpand }else if node.depth == 1{ let cell = tableView.cellForRow(at: indexPath) as! IHSecondaryCell cell.isExpand = node.isExpand }else{ let cell = tableView.cellForRow(at: indexPath) as! IHThirdGradeCell cell.isExpand = node.isExpand } treeDelegate?.treeCellClick(node: node, indexPath: indexPath) if isLeafNode(node: node) { //叶子节点 return }else{//节点cell if node.isExpand {// 当前节点展开,要进行收缩操作 deleteIndexPaths = [IndexPath]() deleteChildNode(node: node) self.tableView.deleteRows(at: deleteIndexPaths, with: .top) }else{ //当前节点搜索,要进行展开操作 insertIndexPaths = [IndexPath]() insertChildNode(node: node) self.tableView.insertRows(at: insertIndexPaths, with: .top) } } } }