使用TableView实现多级树型menu

官方UIKit下的TableView,支持section和row的显示,但不支持在talbeview里显示多级树型结构的menu,因为项目需要便写了一个支持多级目录显示menu的Demo(下载传送门)。支持菜单展开动画效果,支持级联打开下下级子目录。

效果图如下:


要现实多级目录,首先要做的是在内存构建树型结构,通过这个树型结构,当用户点击了某个有子项的菜单,其变会根据树型结构将menu展开或收起。

下面是“树”中节点的构造,在这里并没有使用CFTree,出于两点考虑:一是menu的结构一般只需知道其子菜单即可,是一个简单应用;第二是项目内部对C++不了的童鞋。

  1. @interfaceMyItem:NSObject
  2. @property(nonatomic,retain)NSString*title;
  3. @property(nonatomic)NSIntegerlevel;
  4. @property(nonatomic,retain)NSMutableArray*subItems;
  5. @property(nonatomic)BOOLisSubItemOpen;
  6. @property(nonatomic)BOOLisCascadeOpen;
  7. @end
其中,subItems这个数组,存放该节点的子菜单,使用isSubItemOpen来标记自菜单是否被打开,使用isCascadeOpen标记该子菜单是否要在其父菜单展开时自动展开。

菜单级联收起代码

  1. -(NSMutableArray*)cascadingDeletePaths:(NSIndexPath*)indexPath
  2. {
  3. [treeItemsToRemoveremoveAllObjects];
  4. MyItem*item;
  5. item=[_tableViewDataobjectAtIndex:indexPath.row];
  6. [selfcascadingDeleteCellPaths:item];
  7. NSMutableIndexSet*set;
  8. set=[NSMutableIndexSetindexSet];
  9. for(inti=0;i<[treeItemsToRemovecount];i++){
  10. NSIndexPath*index;
  11. index=[treeItemsToRemoveobjectAtIndex:i];
  12. [setaddIndex:index.row];
  13. }
  14. item.isSubItemOpen=NO;
  15. [_tableViewDataremoveObjectsAtIndexes:set];
  16. returntreeItemsToRemove;
  17. }
  18. -(void)cascadingDeleteCellPaths:(MyItem*)item
  19. {
  20. for(inti=0;i<[item.subItemscount]&&item.isSubItemOpen;i++){
  21. MyItem*item1;
  22. item1=[item.subItemsobjectAtIndex:i];
  23. NSLog(@"sub%@",item1);
  24. NSIndexPath*path=[NSIndexPathindexPathForRow:[_tableViewDataindexOfObject:item1]inSection:0];
  25. [selfcascadingDeleteCellPaths:item1];
  26. [treeItemsToRemoveaddObject:path];
  27. item1.isSubItemOpen=NO;
  28. }
  29. }
其中使用cascadingDeleteCellPaths函数的递归调用,来完成对item子树的遍历。


在tableViewController里逻辑要尽量简单,其中在tableView:didSelectRowAtIndexPath里代码如下

  1. MenuItemCell*cell;
  2. cell=(MenuItemCell*)[tableViewcellForRowAtIndexPath:indexPath];
  3. if(cell.item.isSubItemOpen)
  4. {
  5. //remove
  6. NSArray*arr;
  7. arr=[_menuDatacascadingDeletePaths:indexPath];
  8. if([arrcount]>0){
  9. [tableViewdeleteRowsAtIndexPaths:arrwithRowAnimation:UITableViewRowAnimationBottom];
  10. }
  11. }
  12. else
  13. {
  14. //insert
  15. NSArray*arr;
  16. arr=[_menuDatacascadingInsertCellPaths:indexPath];
  17. if([arrcount]>0){
  18. [tableViewinsertRowsAtIndexPaths:arrwithRowAnimation:UITableViewRowAnimationBottom];
  19. }
  20. }

其中,cell的插入和移除的动画,使用withRowAnimation完成。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值