在我们的日常开发工作中,UITableview用的频率是很高的,主要用来进行数据展示,以及其他的必要时候的使用。
一、像QQ好友列表那样可以展开一级的tableviwe表格
*****注:主要是点击tableviwe的headerview进行数据的操作,刷新表格,从而实现row的出现和消失,下面是主要的代码*****
1.创建必要的类
1.1用于储存数据的模型类DetailModel
@interface DetailModel : NSObject
/** 标题,内容 */
@property (nonatomic ,strong) NSString *title;
/** 是否展开 */
@property (nonatomic , assign) BOOL isOpen;
/** 数组 */
@property (nonatomic , copy) NSMutableArray *subTitle;
/** model的级别 */
@property (nonatomic , assign) NSInteger modelLeval;
/**
判断这个模型里面应该展示的数据个数,也就是打开的数据的个数
@return 数据的个数
*/
+ (NSInteger)numberOfOpen:(DetailModel *)model;
/**
返回这个模型里面所有打开的模型数组
@param model 需要查看的模型
@return 模型里面所有打开的模型的数组
*/
+ (NSMutableArray *)subTitleOfOpen:(DetailModel *)model;
@end
1.2用于展示可点击列表的view类DetailView,并且定义协议DetailViewDelegate
@protocol DetailViewDelegate
- (void)DetailView:(DetailView *)dv IsOpen:(BOOL)isOpen;
@end
@interface DetailView : UIView
/** 标题,内容 */
@property (nonatomic ,strong) NSString *title;
/** 是否展开 */
@property (nonatomic , assign) BOOL isOpen;
/** 所在的表格 */
@property (nonatomic ,strong) UITableView *tabble;
/** view对应的数据模型 */
@property (nonatomic ,strong) DetailModel *model;
/** 协议的属性 */
@property (nonatomic , assign) id delegate;
@end
2.进行数据准备
2.1将子标题添加到model的subTitle里面
- (void)setSubTitle:(NSMutableArray *)subTitle
{
NSMutableArray *subs = [NSMutableArray array];
if ([subTitle isEqual: @""]) {
[subs removeAllObjects];
return ;
}
for (NSDictionary *dic in subTitle) {
DetailModel *dm = [[DetailModel alloc] init];
[dm setValuesForKeysWithDictionary:dic];
[subs addObject:dm];
}
_subTitle = subs;
}
2.2根据传进来的model判断处于打开状态的model数量,即可以展示的模型个数
+ (NSInteger)numberOfOpen:(DetailModel *)model
{
NSInteger num = 0;
// 1.计算model的子标题的个数
num = model.isOpen ? model.subTitle.count : 0;
// 2.判断model是否为打开状态,若是的话进行递归操作
if (num) {
for (DetailModel *submodel in model.subTitle) {
num += [DetailModel numberOfOpen:submodel];
}
}
return num;
}
2.3根据传进来的model找出所有可以展示的模型的个数,添加到指定数组并返回
+ (NSMutableArray *)subTitleOfOpen:(DetailModel *)model
{
NSMutableArray *array = [NSMutableArray array];
NSInteger num = 0;
// 1.若果是打开状态就直接将子标题数组添加到需要返回的数组里面
if (model.isOpen) {
[array addObjectsFromArray:model.subTitle];
// 2.便利数组查看数组模型中是否都为打开状态
for (NSInteger i = 0; i < model.subTitle.count; i ++) {
DetailModel *submodel = model.subTitle[i];
// 3.进行递归查询,子标题是否为打开状态
NSMutableArray *dmsA = [DetailModel subTitleOfOpen:submodel];
if (dmsA.count) {
for (NSInteger j = 0; j < dmsA.count; j ++) {
num ++;
DetailModel *detailModel = dmsA[j];
// 判断需要添加模型的位置,若是最后面则进行add操作,若是中间的就进行insert操作
if (num + i + 1 > array.count) {
[array addObject:detailModel];
} else {
[array insertObject:detailModel atIndex:num + i];
}
}
}
}
}
return array;
}
3.添加用于展示数据的UITableview,展示可点击的列表(只写必要的方法)
3.1将表格的headerview换成自定义的detailview并设置其代理,用于监听点击事件
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
DetailModel *dm = self.array[section];
DetailView *dv = [[DetailView alloc] init];
dv.model = dm;
dv.delegate = self;
return dv;
}
3.2实现代理方法,进行数据刷新
#pragma mark --- DetailView的代理事件
- (void)DetailView:(DetailView *)dv IsOpen:(BOOL)isOpen
{
NSLog(@"----delegate-----%d--%@",isOpen,dv.model);
dv.model.isOpen = isOpen;
[self.tableView reloadData];
}
附上DetailView的通知代理的点击方法
- (void)DetailViewClick:(UITapGestureRecognizer *)tap
{
self.isOpen = !self.isOpen;
[_delegate DetailView:(DetailView *)tap.view IsOpen:self.isOpen];
}
至此就可以实现类似QQ好友列表的tableview的两级菜单点击
二、实现多级菜单的点击(在二级菜单上进行稍微的修改就行)
注:主要适用于菜单列表详细的项目,如行政区域划分等
1.创建必要的类(只有自定义cell其余的按照二级菜单来)
@interface DetailTableViewCell : UITableViewCell
/** DetailVi */
@property (nonatomic ,strong) DetailModel *dm;
/** self.dv */
@property (nonatomic ,strong) DetailView *dv;
@end
2.进行数据展示(数据准备的按二级菜单来,数据展示也只写多出的部分,其余都为二级菜单照搬即可)
2.1计算出需要展示的row的个数
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
DetailModel *dm = self.array[section];
NSInteger ss = [DetailModel numberOfOpen:dm];
NSLog(@"这组里面有%ld",ss);
return ss;
}
2.2返回指定的cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
DetailModel *dm = self.array[indexPath.section];
self.dmsArray = [DetailModel subTitleOfOpen:dm];
DetailModel *dms = self.dmsArray[indexPath.row];
NSString *cell_normal = @"cell_normal";
NSString *cell_detail = @"cell_Detail";
if (dms.subTitle == nil) {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cell_normal];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cell_normal];
}
cell.textLabel.text = dms.title;
return cell;
} else {
DetailTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cell_detail];
if (!cell) {
cell = [[DetailTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cell_detail];
}
cell.dm = dms;
cell.dv.delegate = self;
return cell;
}
}
*****注:加上下面的方法可以防止tableview出现白条*****
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
return CGFLOAT_MIN;
}
-----------------------至此已经实现了多级菜单-----------------------------
理解多级菜单的主旨就好了,本身还是一个tableview,只是对section里面的数据进行整理,出现多级点击的效果
求助!!!求助!!!求助!!!小编想在代码里面实现如图里面所展示的北京市为一级菜单就是+1海淀区是二级菜单就+2中关村是三级菜单就+3以此类推的效果,试了好多方法都不行,如果有大神看到的话,请指点一二,拜谢
下面附上demo的地址:MenueTableview