使用TableView实现多级树型menu

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

效果图如下:


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

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

#import <Foundation/Foundation.h>
@interface MyItem : NSObject
@property (nonatomic,retain)  NSString * title;
@property (nonatomic) NSInteger level;
@property (nonatomic, retain) NSMutableArray *subItems;
@property (nonatomic) BOOL isSubItemOpen;
@property (nonatomic) BOOL isSubCascadeOpen;
@end


其中,subItems这个数组,存放该节点的子菜单,使用isSubItemOpen来标记自菜单是否被打开,使用isCascadeOpen标记该子菜单是否要在其父菜单展开时自动展开。

菜单级联收起代码

#pragma mark -- insert
- (NSArray *)insertMenuIndexPaths:(MyItem *)item
{
    NSArray * arr;
    [treeItemsToInsert removeAllObjects];
    [self insertMenuObject:item];
    arr = [self insertIndexsOfMenuObject:treeItemsToInsert];
    return arr;
}
- (void) insertMenuObject:(MyItem *)item
{
    NSLog(@"%d",[_tableViewData indexOfObject:item]);
    if (item == nil)
    {
        return ;
    }
    
    NSIndexPath *path = [NSIndexPath indexPathForRow:[_tableViewData indexOfObject:item] inSection:0];
    
    MyItem *childItem;
    for (int i = 0; i<[item.subItems count] ; i++) {
        childItem = [item.subItems objectAtIndex:i];
        [_tableViewData insertObject:childItem atIndex:path.row + i +1];
        [treeItemsToInsert addObject:childItem];
        item.isSubItemOpen = YES;
    }
    
    for (int i = 0; i <[item.subItems count]; i ++) {
        childItem = [item.subItems objectAtIndex:i];
        
        if (childItem .isSubCascadeOpen) {
            [self insertMenuObject:childItem];
        }
        
    }
    return ;
    
}
- (NSArray *) insertIndexsOfMenuObject :(NSMutableArray *) array
{
    
    NSMutableArray * mutableArr;
    mutableArr = [NSMutableArray array];
    for (MyItem * item in array) {
        NSIndexPath *path = [NSIndexPath indexPathForRow:[_tableViewData indexOfObject:item] inSection:0];
        [mutableArr addObject:path];
    }
    return mutableArr;
}

其中使用insertMenuObject函数的递归调用,来完成对item子树的遍历


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

    MenuItemCell * cell;
    cell = (MenuItemCell *)[tableView cellForRowAtIndexPath:indexPath];
    if (cell.item.isSubItemOpen)
    {
        //remove
        NSArray * arr;
        arr = [_menuData deleteMenuIndexPaths:cell.item];
        if ([arr count] >0) {
            [tableView deleteRowsAtIndexPaths: arr withRowAnimation:UITableViewRowAnimationBottom];
        }
    }
    else
    {
        //insert
        NSArray * arr;
        arr = [_menuData insertMenuIndexPaths:cell.item];
        if ([arr count] >0) {
            [tableView insertRowsAtIndexPaths:arr withRowAnimation:UITableViewRowAnimationBottom];
        }
    }



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






  • 6
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值