您的位置:首页 > 其它

TableView区域的折叠打开(仿QQ)

2015-12-02 21:49 330 查看
很早就想把这个总结一下了, 可惜最近一直在搞XAMPP, 还老是出各种问题奇葩, 今天总算搞定了, 赶紧把这个功能实现一下, 先看一下效果



这是解析的全国省市的一个plist文件, 至于排序这里就不处理了

先说一下思路(个人思路, 以后有空研究研究大神们的):

1. 区头添加触发动作的操作, a. 添加button; b.手势

2. 存放该区状态(开合)的数组

3. 判断点击的是哪个section的区头, 使用代理

重写UITableViewHeaderFooterView

@class ZHZHeaderView;
/**
*  协议
*  作用: 传值(点击区头的section 和 区头view)
*  @param section  区头的section
*  @param headview 区头view
*/
@protocol HeaderProtocol <NSObject>

- (void)clickHeaderOfSection:(NSInteger)section headView:(ZHZHeaderView *)headview;

@end

@interface ZHZHeaderView : UITableViewHeaderFooterView

@property (nonatomic, assign)id<HeaderProtocol> delegate;

/**
*  添加 轻击 手势
*/
@property (nonatomic, strong)UITapGestureRecognizer *tap;

@end


@implementation ZHZHeaderView

//布局子控件时添加 tap手势
- (void)layoutSubviews {
[super layoutSubviews];

self.contentView.backgroundColor = [UIColor redColor];
[self.contentView addGestureRecognizer:self.tap];

}

#pragma mark - Action
- (void)tapAction:(UITapGestureRecognizer *)tap {
if ([self.delegate respondsToSelector:@selector(clickHeaderOfSection:headView:)]) {
[self.delegate clickHeaderOfSection:self.tag headView:self];
}
}

#pragma mark - Getter
- (UITapGestureRecognizer *)tap {
if (_tap == nil) {
_tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction:)];
}
return _tap;
}

#pragma mark - life
- (void)dealloc
{
[self removeGestureRecognizer:self.tap];
}
@end


遵守协议, 实现 区域 开合

#import "ZHZTableViewController.h"
#import "ZHZHeaderView.h"

@interface ZHZTableViewController ()<HeaderProtocol>
///数据字典
@property (nonatomic, strong)NSDictionary *cityDict;
///存放每个区域状态
@property (nonatomic, strong)NSMutableArray *foldArr;

@end

@implementation ZHZTableViewController

- (void)viewDidLoad {
[super viewDidLoad];

//请求数据
[self requestData];

[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"reuseIdentifier"];
[self.tableView registerClass:[ZHZHeaderView class] forHeaderFooterViewReuseIdentifier:@"header"];
}

/**
*  请求数据
*/
- (void)requestData {

NSString *str = [[NSBundle mainBundle] pathForResource:@"citydict.plist" ofType:nil];
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:str];

self.cityDict = [NSDictionary dictionaryWithDictionary:dict];
self.foldArr = [NSMutableArray arrayWithCapacity:0];

for (int i = 0; i <[self.cityDict allKeys].count; i++) {
[self.foldArr addObject:@0];
}
}

#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [self.cityDict allKeys].count;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSString *str = [self.cityDict allKeys][section];
//根据self.foldArr存放的状态,判断区域的开合
if ([self.foldArr[section] integerValue]) {
return [self.cityDict[str] count];
}
return 0;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"reuseIdentifier" forIndexPath:indexPath];
NSString *key = [self.cityDict allKeys][indexPath.section];
NSArray *arr = self.cityDict[key];
cell.textLabel.text = arr[indexPath.row];

return cell;
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
NSString *key = [self.cityDict allKeys][section];
return key;
}

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {

ZHZHeaderView *headView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:@"header"];
headView.tag = section;
headView.delegate = self;

return headView;
}

#pragma mark -HeaderProtocol
- (void)clickHeaderOfSection:(NSInteger)section headView:(ZHZHeaderView *)headview{

self.foldArr[section] = @(![self.foldArr[section] integerValue]);
//[self.tableView scrollToNearestSelectedRowAtScrollPosition:UITableViewScrollPositionTop animated:YES];
//[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathWithIndex:section] atScrollPosition:UITableViewScrollPositionTop animated:YES];
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:section] withRowAnimation:UITableViewRowAnimationNone];
}

@end


OK, 搞定!!

补充: 使用block 替代delegate

重命名 block的 变量类型
typedef void(^MyBlock)(NSInteger section, ZHZHeaderView *headerView);
/**
*  block传值
*  方便调用
*/
- (void)sectionHeaderBlock:(MyBlock)block;


#pragma mark - Action
//2. 点击headView时调用
- (void)tapAction:(UITapGestureRecognizer *)tap {
if (self.myBlock) {
//防止循环引用(因为self拥有block, block也拥有self)
__weak typeof(self) weakSelf = self;
self.myBlock(weakSelf.tag, weakSelf);
}
}

//1. 运行时首先调用 sectionHeaderBlock
- (void)sectionHeaderBlock:(MyBlock)block {
//外面的block中的代码片段传过来
self.myBlock = block;

}


创建headerView时直接调用, 清楚明白

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {

ZHZHeaderView *headView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:@"header"];
headView.tag = section;

//调用block函数
[headView sectionHeaderBlock:^(NSInteger section, ZHZHeaderView *headerView) {
//代码片段会保存起来, 等到点击的时候才调用
self.foldArr[section] = @(![self.foldArr[section] integerValue]);
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:section] withRowAnimation:UITableViewRowAnimationNone];
}];

return headView;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: