ios开发之级联菜单(两个tableView实现)
一:在ios项目实际开发中经常会看到级联菜单的效果:如图:点击左侧菜单,右侧菜单刷新数据。此篇用两个tableView来实现如图效果:

二:代码:
1:构造数据模型:利用kvc快速构建数据模型
#import <Foundation/Foundation.h> @interface XMGCategory : NSObject
/** 子类别 */
@property (nonatomic, strong) NSArray *subcategories;
/** 姓名 */
@property (nonatomic, strong) NSString *name;
/** 图标 */
@property (nonatomic, strong) NSString *icon;
/** 高亮图标 */
@property (nonatomic, strong) NSString *highlighted_icon; + (instancetype)categoryWithDict:(NSDictionary *)dict;
@end
#import "XMGCategory.h" @implementation XMGCategory
+ (instancetype)categoryWithDict:(NSDictionary *)dict
{
XMGCategory *c = [[self alloc] init];
[c setValuesForKeysWithDictionary:dict];
return c;
}
@end
2:控制器代码实现:
#import "ViewController.h"
#import "XMGCategory.h" @interface ViewController () <UITableViewDataSource, UITableViewDelegate>
/** 右边表格 */
@property (weak, nonatomic) IBOutlet UITableView *subcategoryTableView;
/** 左边表格 */
@property (weak, nonatomic) IBOutlet UITableView *categoryTableView;
/** 所有的类别数据 */
@property (nonatomic, strong) NSArray *categories;
@end @implementation ViewController #pragma mark -- 懒加载数据源
- (NSArray *)categories
{
if (!_categories) {
//1:从plist文件中读取数据
NSArray *dictArray = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"categories" ofType:@"plist"]];
//2:构造数据源
NSMutableArray *categoryArray = [NSMutableArray array];
for (NSDictionary *dict in dictArray) {
[categoryArray addObject:[XMGCategory categoryWithDict:dict]];
} //3:赋值数据源
_categories = categoryArray;
}
return _categories;
} - (void)viewDidLoad {
[super viewDidLoad]; //1:默认选中左边表格的第0行
[self.categoryTableView selectRowAtIndexPath:[NSIndexPath indexPathForRow: inSection:] animated:NO scrollPosition:UITableViewScrollPositionTop]; //2:给右侧的tableView增加额外的滚动区域:在有导航栏的时候,系统默认会为UIScrollView或是继承它的子控件默认增加64的额外滚动区域,如果有两个继承于UIScrollView的子控件,则系统默认只会为第一个添加到视图上的子控件增加额外的滚动区域。如果想禁止,则实现UIScrollView或是tableView等的ContentInset属性,增加额外的滚动区域,或是在控制器中实现self.automaticallyAdjustsScrollViewInsets = NO;
self.subcategoryTableView.contentInset = UIEdgeInsetsMake(, , , );
} - (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated]; NSLog(@"categoryTableView - %@", NSStringFromUIEdgeInsets(self.categoryTableView.contentInset));
NSLog(@"subcategoryTableView - %@", NSStringFromUIEdgeInsets(self.subcategoryTableView.contentInset));
} #pragma mark - Table view data source
- (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;
} - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// 左边表格
if (tableView == self.categoryTableView) {
static NSString *ID = @"category";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; XMGCategory *c = self.categories[indexPath.row]; // 设置普通图片
cell.imageView.image = [UIImage imageNamed:c.icon];
// 设置高亮图片(cell选中 -> cell.imageView.highlighted = YES -> cell.imageView显示highlightedImage这个图片)
cell.imageView.highlightedImage = [UIImage imageNamed:c.highlighted_icon]; // 设置label高亮时的文字颜色
cell.textLabel.highlightedTextColor = [UIColor redColor]; cell.textLabel.text = c.name;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; return cell;
} else {
// 右边表格
static NSString *ID = @"subcategory";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; // 获得左边表格被选中的模型
XMGCategory *c = self.categories[self.categoryTableView.indexPathForSelectedRow.row];
cell.textLabel.text = c.subcategories[indexPath.row]; return cell;
}
} #pragma mark - <UITableViewDelegate>
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView == self.categoryTableView) {
[self.subcategoryTableView reloadData];
}
}
三:知识点总结:
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];
ios开发之级联菜单(两个tableView实现)的更多相关文章
- iOS开发UI篇—推荐两个好用的Xcode插件(提供下载链接)
iOS开发UI篇—推荐两个好用的Xcode插件(提供下载链接) 这里推荐两款好用的Xcode插件,并提供下载链接. 一.插件和使用如下: 1.两款插件 对项目中图片提供自动提示功能的插件:KSImag ...
- iOS 类似美团外卖 app 两个 tableView 联动效果实现
写在前面 首先声明哈,不是广告,我就是用的时候觉得这个功能比较好玩,就想着实现了一下.效果如图: 接下来简单的说一下思路吧~ 大体思路 可能我们看到这种功能的实现的时候,首先想着的是我在这个控制器中左 ...
- IOS开发复习笔记(4)-TableView
总结几个TableView常用的代码 1.初始化方面 static string CellIndetifier=@"cellIndetifier"; -(NSInteger)num ...
- ---iOS开发 截取字符串中两个指定字符串中间的字符串---
例如,要截取一个字符串中,两个指定字符串中间的字符串,OC截取方法如下: // 要截取 "> 和 </ 之间的汉字内容: @implementationViewControlle ...
- iOS开发NSFetchedResultsController的使用CoreData和TableView数据同步更新
1.效果 2.代码 #import "ViewController.h" #import "Student+CoreDataProperties.h" #def ...
- iOS开发之转盘菜单
前言 使用Swift实现的转盘菜单,主要用到UIBezierPath.CALayer遮罩绘制扇形UIView,CATransform3DMakeRotation实现旋转动画.代码设计使用默认confi ...
- iOS 类似外卖 两个tableView联动
在伯乐在线上看到一个挺好玩的文章,自己也参考文章实现了一下. 效果实现如图所示: 具体实现的内容可以参考原文,参考文章:<iOS 类似美团外卖 app 两个 tableView 联动效果实现&g ...
- iOS开发小技巧 -- tableView-section圆角边框解决方案
[iOS开发]tableView-section圆角边框解决方案 tableView圆角边框解决方案 iOS 7之前,图下圆角边框很容易设置 iOS 7之后,tableviewcell的风格不再是圆角 ...
- 文顶顶iOS开发博客链接整理及部分项目源代码下载
文顶顶iOS开发博客链接整理及部分项目源代码下载 网上的iOS开发的教程很多,但是像cnblogs博主文顶顶的博客这样内容图文并茂,代码齐全,示例经典,原理也有阐述,覆盖面宽广,自成系统的系列教程 ...
随机推荐
- Linux下SPI读写外部寄存器的操作
SPI写寄存器操作: staticvoid mcp251x_write_reg(struct spi_device *spi, uint8_t reg, uint8_t val) { stru ...
- 65.十一级指针实现百万qq号的增删查改以及排序写入
运行结果: 内存使用情况: 写入文件排序好的数据: 创建文件地址以及创建十一级指针 char *path = "QQ.txt"; char *sortpath = "QQ ...
- jquery如何阻止子元素相应mouseout事件
jquery如何阻止子元素相应mouseout事件:mouseout有一个特点,当鼠标移入子元素的时候,也会触发此事件,但是在实际应用中这个特点往往不是我们想要的,下面就通过代码实例介绍一下如何实现此 ...
- buildroot使用
buildroot是一套自动化构建工具,比yocto简单. 项目地址:http://www.buildroot.org/ 培训资料地址:http://free-electrons.com/ 附带lin ...
- 自定义Base 64加密
一.前言 最近做软件需要一个功能,就是对文件进行加密.本来嘛,加密算法一堆一堆的,但是试了几个成熟的加密算法后发现对文件进行加密需要的时间很长,特别是上G的文件,这样客户是接受不了的.最后没办法了,好 ...
- 03002_MySQL数据库的安装和配置
1.MySQL的安装 (1)下载mysql-5.5.49-win32.msi, 链接:MySQL安装包下载 密码:geqh : (2)打开下载的MySQL安装文件mysql-5.5.27-win32. ...
- 【习题 7-5 UVA-690】Pipeline Scheduling
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 一定在这里写完思路再敲代码!!! 处理出5个工作单元在哪些时刻会被用到. ->设为initstatu 因为每次都会面临之前已经 ...
- [TS] Implement a doubly linked list in TypeScript
In a doubly linked list each node in the list stores the contents of the node and a pointer or refer ...
- [Javascript AST] 0. Introduction: Write a simple BabelJS plugin
To write a simple Babel plugin, we can use http://astexplorer.net/ to help us. The plugin we want to ...
- 玩转Bootstrap(基础) -- (6.导航条基础)
1.导航条样例 <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" ...