In the project development, the level list often encounters, the simple point two level list utilizes the UITableView header to be possible, then the simple point three level list by adjusts the cell height to also be possible to achieve the three level list the effect. However, it is troublesome to encounter multilevel lists, especially the dynamic lists with unknown levels.
Principle
A hierarchical list is similar to a tree structure, but not a binary tree, but a fork tree. Each node only needs to have two pointers to the parent node and child nodes to form a tree. We treat each level of an object in a multilevel list as a node,node with two attributes, the ID of the parent node and the child node, respectively.
Each tree has a virtual root node, its ID is rootid, all nodes in the parent node ID is Rootid is the first level, the corresponding tree structure in the depth (depth). So each node object has ParentID and Childrenid, Childrenid is the ID of the node object.
We can detect the first node through the Rootid, and then according to the first level of node Childrenid detect the next level, and so on, and so on to determine the parent-child relationship of all nodes. It is also possible to determine the leaf node and the first level node, which can also be called
As the root node.
Effect chart
1. General Multilevel List
2. Record node history state of the list
Ideas
1. First, according to Rootid get all the first-level nodes, and put into the UITableView data source Datasourcearr, show the initialization of the list
2. Expand: Click on the node cell, according to Childrenid find the next level nodes, and insert into the Datasourcearr currentnode behind, refresh the display
3. Fold: Click to open the node cell, starting from the Datasourcearr currentindex+1, if the level of the node is less than the level of currentnode, then remove node, otherwise stop refreshing the list.
4. Click on the cell as the leaf node does not respond to expand or fold operation, and the node information by return.
In Datasourcearr, this is an order that conforms to the tree hierarchy:
Defining Node Objects
Encounter problems
1. Local refresh Problem
Refresh the list after each expansion or start up with
Copy Code code as follows:
-(void) Reloadsections: (Nsindexset *) Sections withrowanimation: (uitableviewrowanimation) animation
But will cause the program to have the whole flicker effect, the experience is not good. Finally, the partial refresh insertrowsatindexpaths and deleterowsatindexpaths are considered.
But the error will be in the refresh
* Terminating app due to uncaught exception ' nsinternalinconsistencyexception ', Reason: ' Attempt to delete row 2 from sect Ion 0 which only contains 2 rows before the update '
The reason is that the current cell numberofrowsinsection when it refreshes and refreshes the cell when the insert or del is numberofrowsinsection. Then try to refresh the current cell and the other cell separately, and refresh it perfectly.
[_reloadarray removeallobjects];
[TableView Reloadrowsatindexpaths:@[indexpath] withrowanimation:uitableviewrowanimationnone];
if (Currentnode.isexpand) {
//expand
[self ExpandNodesForParentID:currentNode.childrenID insertindex: Indexpath.row];
[TableView Insertrowsatindexpaths:_reloadarray withrowanimation:uitableviewrowanimationnone];
} else{
//fold
[self foldNodesForLevel:currentNode.level currentIndex:indexPath.row];
[TableView Deleterowsatindexpaths:_reloadarray withrowanimation:uitableviewrowanimationnone];
}
2. How to save the node history state
When the file level is relatively long, sometimes you want to turn off the hierarchy and then open it to keep the child level Open. We can give each node a property that expands, and when fold modifies only the expand attribute of the CurrentNode, the expand iterates through the child node sequence isexpand=yes.
Expand
-(Nsuinteger) Expandnodesforparentid: (nsstring*) ParentID Insertindex: (nsuinteger) insertindex{
for (int i = 0; i<_nodes.count;i++) {
Yknodemodel *node = _nodes[i];
if ([Node.parentid Isequaltostring:parentid]) {
if (!self.ispreservation) {
node.expand = NO;
}
insertindex++;
[_tempnodes Insertobject:node Atindex:insertindex];
[_reloadarray addobject:[nsindexpath indexpathforrow:insertindex insection:0]];//need Reload
if ( Node.isexpand) {
insertindex = [self ExpandNodesForParentID:node.childrenID insertindex:insertindex];
}
}
}
return insertindex;
}
Demo Address:
Https://github.com/YangKa/YKMutableLevelTableView.git
The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.