天天看點

ios開發之級聯菜單(兩個tableView實作)

一:在ios項目實際開發中經常會看到級聯菜單的效果:如圖:點選左側菜單,右側菜單重新整理資料。此篇用兩個tableView來實作如圖效果:

ios開發之級聯菜單(兩個tableView實作)

二:代碼:

1:構造資料模型:利用kvc快速建構資料模型

1 #import <Foundation/Foundation.h>
 2 
 3 @interface XMGCategory : NSObject
 4 /** 子類别 */
 5 @property (nonatomic, strong) NSArray *subcategories;
 6 /** 姓名 */
 7 @property (nonatomic, strong) NSString *name;
 8 /** 圖示 */
 9 @property (nonatomic, strong) NSString *icon;
10 /** 高亮圖示 */
11 @property (nonatomic, strong) NSString *highlighted_icon;
12 
13 + (instancetype)categoryWithDict:(NSDictionary *)dict;
14 @end      
1 #import "XMGCategory.h"
 2 
 3 @implementation XMGCategory
 4 + (instancetype)categoryWithDict:(NSDictionary *)dict
 5 {
 6     XMGCategory *c = [[self alloc] init];
 7     [c setValuesForKeysWithDictionary:dict];
 8     return c;
 9 }
10 @end      

2:控制器代碼實作:

1 #import "ViewController.h"
  2 #import "XMGCategory.h"
  3 
  4 @interface ViewController () <UITableViewDataSource, UITableViewDelegate>
  5 /** 右邊表格 */
  6 @property (weak, nonatomic) IBOutlet UITableView *subcategoryTableView;
  7 /** 左邊表格 */
  8 @property (weak, nonatomic) IBOutlet UITableView *categoryTableView;
  9 /** 所有的類别資料 */
 10 @property (nonatomic, strong) NSArray *categories;
 11 @end
 12 
 13 @implementation ViewController
 14 
 15 #pragma mark -- 懶加載資料源
 16 - (NSArray *)categories
 17 {
 18     if (!_categories) {
 19         //1:從plist檔案中讀取資料
 20         NSArray *dictArray = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"categories" ofType:@"plist"]];
 21         //2:構造資料源
 22         NSMutableArray *categoryArray = [NSMutableArray array];
 23         for (NSDictionary *dict in dictArray) {
 24             [categoryArray addObject:[XMGCategory categoryWithDict:dict]];
 25         }
 26         
 27         //3:指派資料源
 28         _categories = categoryArray;
 29     }
 30     return _categories;
 31 }
 32 
 33 - (void)viewDidLoad {
 34     [super viewDidLoad];
 35     
 36     //1:預設選中左邊表格的第0行
 37     [self.categoryTableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] animated:NO scrollPosition:UITableViewScrollPositionTop];
 38     
 39     //2:給右側的tableView增加額外的滾動區域:在有導航欄的時候,系統預設會為UIScrollView或是繼承它的子控件預設增加64的額外滾動區域,如果有兩個繼承于UIScrollView的子控件,則系統預設隻會為第一個添加到視圖上的子控件增加額外的滾動區域。如果想禁止,則實作UIScrollView或是tableView等的ContentInset屬性,增加額外的滾動區域,或是在控制器中實作self.automaticallyAdjustsScrollViewInsets = NO;
 40     self.subcategoryTableView.contentInset = UIEdgeInsetsMake(64, 0, 0, 0);
 41 }
 42 
 43 - (void)viewDidAppear:(BOOL)animated
 44 {
 45     [super viewDidAppear:animated];
 46     
 47     NSLog(@"categoryTableView - %@", NSStringFromUIEdgeInsets(self.categoryTableView.contentInset));
 48     NSLog(@"subcategoryTableView - %@", NSStringFromUIEdgeInsets(self.subcategoryTableView.contentInset));
 49 }
 50 
 51 #pragma mark - Table view data source
 52 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
 53     // 左邊表格
 54     if (tableView == self.categoryTableView) return self.categories.count;
 55     
 56     // 右邊表格
 57     XMGCategory *c = self.categories[self.categoryTableView.indexPathForSelectedRow.row];
 58     return c.subcategories.count;
 59 }
 60 
 61 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
 62     // 左邊表格
 63     if (tableView == self.categoryTableView) {
 64         static NSString *ID = @"category";
 65         UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
 66         
 67         XMGCategory *c = self.categories[indexPath.row];
 68         
 69         // 設定普通圖檔
 70         cell.imageView.image = [UIImage imageNamed:c.icon];
 71         // 設定高亮圖檔(cell選中 -> cell.imageView.highlighted = YES -> cell.imageView顯示highlightedImage這個圖檔)
 72         cell.imageView.highlightedImage = [UIImage imageNamed:c.highlighted_icon];
 73         
 74         // 設定label高亮時的文字顔色
 75         cell.textLabel.highlightedTextColor = [UIColor redColor];
 76         
 77         cell.textLabel.text = c.name;
 78         cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
 79         
 80         return cell;
 81     } else {
 82         // 右邊表格
 83         static NSString *ID = @"subcategory";
 84         UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
 85         
 86         // 獲得左邊表格被選中的模型
 87         XMGCategory *c = self.categories[self.categoryTableView.indexPathForSelectedRow.row];
 88         cell.textLabel.text = c.subcategories[indexPath.row];
 89         
 90         return cell;
 91     }
 92 }
 93 
 94 #pragma mark - <UITableViewDelegate>
 95 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
 96 {
 97     if (tableView == self.categoryTableView) {
 98         [self.subcategoryTableView reloadData];
 99     }
100 }      

三:知識點總結:

1:級聯菜單資料模型的設計:1:左側表格資料模型中含有右側表格的資料模型,在定義資料模型時,可用類方法,或是執行個體方法:類方法實作:alloc建立對象,對象調用KVC快速為屬性指派,利用KVC必須滿足屬性一一對應,不能少也不多

+ (instancetype)categoryWithDict:(NSDictionary *)dict

{

    XMGCategory *c = [[self alloc] init];

    [c setValuesForKeysWithDictionary:dict];

    return c;

}

2:在構造資料源時:要看清plist根節點是數組還是字典:一般自定義plist資料模型時時,最外層為數組,數組為每一個資料模型的字典:資料源,采用懶加載,懶加載保證隻初始化一次,且不用關心何時建立也就是不用考慮代碼順序。從plist中讀取資料:

 NSArray *dictArray = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"categories" ofType:@"plist"]];

因為懶加載時,資料源本身就沒有初始化,不存在,是以用

 _categories = categoryArray;來對資料源進行指派,若是初始化了,則可以addObjectFromeArray,或是插入資料:insetObject  atIndexSets

3:tableView預設選中某一行:

 //1:預設選中左邊表格的第0行

    [self.categoryTableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] animated:NO scrollPosition:UITableViewScrollPositionTop];

 4:給UIscrollView,tableView,UICollectionView增加額外的滾動區域調用:contentInset.

給右側的tableView增加額外的滾動區域:在有導航欄的時候,系統預設會為UIScrollView或是繼承它的子控件預設增加64的額外滾動區域,如果有兩個繼承于UIScrollView的子控件,則系統預設隻會為第一個添加到視圖上的子控件增加額外的滾動區域。如果想禁止,則實作UIScrollView或是tableView等的ContentInset屬性,增加額外的滾動區域,或是在控制器中實作self.automaticallyAdjustsScrollViewInsets = NO;

self.subcategoryTableView.contentInset = UIEdgeInsetsMake(64, 0, 0, 0);

5:在方法

- (void)viewDidAppear:(BOOL)animated裡視圖已經出現,在此方法中,也就是視圖出現的時候,能正确列印,調試,或是對控件進行一些設定

6:兩個tableView,在實作資料源或是代理方法時,要區分不同的tableView:如:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    // 左邊表格

    if (tableView == self.categoryTableView) return self.categories.count;

       // 右邊表格

    XMGCategory *c = self.categories[self.categoryTableView.indexPathForSelectedRow.row];

    return c.subcategories.count;

}

  其中,self.categoryTableView.indexPathForSelectedRow,得到的是目前表格選中的indexPath區域

7:UITableViewCell:當某個cell被選中時,系統會預設顯示cell中控件高亮時的狀态,取消選中時,顯示常态:可以設定cell中的UIimageView,lable高亮時的狀态:

      //1: 設定普通圖檔

        cell.imageView.image = [UIImage imageNamed:c.icon];

        // 設定高亮圖檔(cell選中 -> cell.imageView.highlighted = YES -> cell.imageView顯示highlightedImage這個圖檔)

        cell.imageView.highlightedImage = [UIImage imageNamed:c.highlighted_icon];       

    // 2:設定label高亮時的文字顔色

        cell.textLabel.highlightedTextColor = [UIColor redColor];

轉載于:https://www.cnblogs.com/cqb-learner/p/5709385.html