iOS開發-UI控件:使用TableView實現多級樹型menu

文章轉自: http://blog.csdn.net/xunyn/article/details/8567249

官方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裏代碼如下

<pre name="code" class="cpp">    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];  
        }  
    }</pre><br>  
<br>  
<pre></pre>  
<span style="font-size:14px">其中,cell的插入和移除的動畫,使用<span style="font-family:Menlo"></span>withRowAnimation完成。</span>  
<p></p>  
<p><span style="font-family:Menlo"><span style="font-size:20px"><br>  
</span></span><br>  
<br>  
<br>  
</p>  
<p><span style="font-size:18px"><br>  
</span></p>  


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章