iOS多級列表實現代碼_IOS

來源:互聯網
上載者:User

在項目開發中,層級列表經常遇到,簡單點的二級列表利用UITableView的Header就可以實現,再簡單點的三級列表通過對Cell高度進行調整也可以實現三級列表的效果。但遇到多級列表,尤其是層次不明的動態列表就比較麻煩了。

原理

層級列表和樹形結構比較類似,不過不是二叉樹,而是多叉樹。每個節點只需要擁有指向父節點和子節點的兩個指標,就能形成一顆樹。我們將多級列表中每一級對象看作一個node,node擁有兩個屬性,分別為父節點和子節點的ID。

每棵樹有個一個虛擬root節點,它的ID為rootID,所有節點中凡是父節點ID為rootID的便是第一級,對應樹結構中的depth(深度)。這樣每一個node對象就都擁有了parentID和childrenID, childrenID為node對象的ID。

我們可以通過rootID查出第一級node,再根據第一級node的childrenID查出下一級,依次類推,確定所有節點的父子關係。同時也可以確定葉子節點和第一級節點,也可稱

為根節點。

效果圖

1.一般多級列表

2.記錄節點曆史狀態的列表

思路

1.首先根據 rootID 擷取所有第一級節點,並放入UITableView的資料來源 dataSourceArr 中,展示初始化列表

2. 展開: 點擊節點cell,根據 childrenID 尋找下一級nodes,並插入到 dataSourceArr 中currentNode的後面,重新整理展示

3. 收攏: 點選以開啟節點cell,從 dataSourceArr 的CurrentIndex+1開始,如果該節點的level小於currentNode的level,則移除node,否則停止重新整理列表。

4.點擊cell為葉子節點則不響應展開或收攏操作,並把節點資訊通過返回。

dataSourceArr中是這樣的一種符合樹層級結構的順序:

定義節點對象

遇到問題

1.局部重新整理的問題

每次展開或收攏以後重新整理列表,一開始採用

複製代碼 代碼如下:
- (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation

但會導致節目有整體閃爍的效果,體驗不好。最後考慮採用局部重新整理 insertRowsAtIndexPaths 和 deleteRowsAtIndexPaths 。

但在重新整理中會報錯

* Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to delete row 2 from section 0 which only contains 2 rows before the update'

推測原因是 current Cell在重新整理時的numberOfRowsInSection和重新整理insert or del的cell時numberOfRowsInSection不一致導致 。然後嘗試current cell和其他cell分別重新整理,完美重新整理。

[_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.怎麼儲存節點曆史狀態

當檔案級層比較多時,有時希望能關掉層級後再開啟時還能保留子層級的開啟狀態。我們可以會給每一個node一個是否展開的屬性,當fold時只修改currentNode的expand屬性,expand時對子節點序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 nodes   if (node.isExpand) {    insertIndex = [self expandNodesForParentID:node.childrenID insertIndex:insertIndex];   }  } } return insertIndex;}

demo地址:
https://github.com/YangKa/YKMutableLevelTableView.git

以上就是本文的全部內容,希望對大家的學習有所協助,也希望大家多多支援雲棲社區。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.