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

释放双眼,带上耳机,听听看~!

很早就想把这个总结一下了, 可惜最近一直在搞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;
}

人已赞赏
iOS文章

iOS常用的宏(整理)--持续更新

2020-3-5 9:09:21

iOS文章

iOS开发TabeViewCell多选

2020-3-5 12:14:02

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
有新消息 消息中心
搜索