一.主界面的搭建,效果图.设置self.navigationItem.leftBarButtonItems属性.

androidm美团界面项目设计_Source

  • 由于leftBarButtonItem是通过xib文件创建的,通过xib创建的控件默认跟随父控件的大小而变化

androidm美团界面项目设计_数据源_02

  • 解决方法:取消xib的autoLayout,取消xib的高度自动拉伸和宽度自动拉伸

androidm美团界面项目设计_Source_03

    

androidm美团界面项目设计_Source_04

  • 自定义的控件需要外界来更改显示的图片以及文字,所以对外提供以下方法来设置自己显示的图片以及文字

二.leftBarButtonItem点击后是通过Popover来展示的,而且展示的都是一个具有两个TableView的级联菜单,这里自定义了级联菜单的View(下面都叫做LRTableView),用的时候将自定义控件添加到对应的控制器上.但是LRTableView需要被提供数据才能显示想要的内容.

  • 解决方法一:对外提供一个将要显示的模型数据,这种方法导致了LRTableView太依赖模型属性,如果模型属性太多的话不仅要判断传过来的是什么模型,而且还不好控制
  • 解决方法二:模仿苹果的TableView,给自己的LRTableView也写一个数据源,写一个代理(这里用的这种),LRTableView需要数据的时候就不用依赖模型属性了,直接问数据源要数据.

数据源协议:

androidm美团界面项目设计_数据_05

代理协议:

androidm美团界面项目设计_androidm美团界面项目设计_06

  • LRTableView内部需要数据的时候直接调用数据源的方法即可
1 #pragma mark - UITableViewDataSource
 2 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
 3 {
 4     if (tableView == self.leftTableView) { // 左边的表格
 5         // 通过数据源获得行数
 6         return [self.dataSource numberOfRowsInLRViewWithLRView:self];
 7     } else { // 右边的表格
 8         return self.subCategories.count;
 9     }
10 }
11 
12 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
13 {
14     UITableViewCell *cell = nil;
15     if (tableView == self.leftTableView) { // 左边的表格
16         // 创建左边的cell
17         cell = [ChaosLeftCell leftCellWithTableView:tableView];
18         // 通过数据源获得对应行的name
19         cell.textLabel.text = [self.dataSource lrView:self leftTitleInRow:indexPath.row];
20         // 通过数据源设置图片
21         if ([self.dataSource respondsToSelector:@selector(lrView:imageNameForRow:)]) {
22             
23             NSString *imageName = [self.dataSource lrView:self imageNameForRow:indexPath.row];
24             cell.imageView.image = [UIImage imageNamed:imageName];
25         }
26         // 通过数据源设置高亮图片
27         if ([self.dataSource respondsToSelector:@selector(lrView:highlightImageNameForRow:)]) {
28             
29             NSString *highlightImage = [self.dataSource lrView:self highlightImageNameForRow:indexPath.row];
30             cell.imageView.highlightedImage = [UIImage imageNamed:highlightImage];
31         }
32         
33     } else { // 右边的表格
34         // 创建右边的cell
35         cell = [ChaosRightCell rightCellWithTableView:tableView];
36         
37         cell.textLabel.text = self.subCategories[indexPath.row];
38     }
39     return cell;
40 }
41 
42 #pragma mark - UITableViewDelegate
43 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
44 {
45     if (tableView == self.leftTableView) { // 左边的表格
46         // 取出子数据,并保存
47         self.subCategories = [self.dataSource lrView:self subDataOfLeftRow:indexPath.row];
48         // 刷新数据
49         [self.rightTableView reloadData];
50         // 点击了左边
51         if ([self.delegate respondsToSelector:@selector(lrView:didSelectedLeftRow:)]) {
52             [self.delegate lrView:self didSelectedLeftRow:indexPath.row];
53         }
54     } else { // 右边的表格
55         
56         if ([self.delegate respondsToSelector:@selector(lrView:didSelectedRightRow:andLeftRow:)]) {
57             [self.delegate lrView:self didSelectedRightRow:indexPath.row andLeftRow:[self.leftTableView indexPathForSelectedRow].row];
58         }
59     }
60 }
  • 相应的控制器实现LRTableView的数据源方法                          
  • 实现代理方法,点击LRTableView中的cell发出通知,接受到通知的view或控制器要修改BarButtonItem的文字和图片
  • NavigationController的栈顶控制器监听LRTableView被点击发出的通知,根据传过来的模型数据,重新设置自定义BarButtonItem的文字或者图片.最后记得移除通知