iOS UITableView的嵌套和sectionHeaderView悬停的解决方案
来源:互联网 发布:java提取方法中的泛型 编辑:程序博客网 时间:2024/06/07 18:42
应用情景
情景一:
说明:是不是和tableView的Plain类型一样,其实这个是由两个列表实现的
情景二:
说明:此时,就可以发现和普通的列表有些不一样了
情景三:
说明:笔者最初就是为了实现这种情况,由于项目需求,需要防QQ空间,不同的是需要类型的切换,当时没想到好的解决方案,最后受同事启发,在其demo上进行修改,使得tableView可以满足大部分的悬停需求
思路说明
1、由于是两个tableView嵌套实现,所以首要就是兼容手势,使得我们的拖拽手势可以向下传递
2、通过改变列表的contentOffset来让列表是否”滚动”
3、子列表默认不滚动,当父列表滚动到需要悬停的位置时,父列表”停止”滚动,子列表开始滚动
4、当子列表下拉,contentOffset.y小于0时,子列表”停止滚动”,父列表开始”滚动”
5、使用通知来接收滚动消息
主要实现过程(代码)
首先继承UITableView新建LolitaTableView类,并定义两种类型
typedef NS_ENUM(NSInteger , LolitaTableViewType) { LolitaTableViewTypeMain, // 父列表 LolitaTableViewTypeSub // 子列表};
1、兼容手势
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{ if (self.type==LolitaTableViewTypeMain) { // 父table类型需要兼容手势 return YES; } return NO;}
2、注册通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(scrollStop:) name:kScrollStopNotificationName object:nil];
3、重写setContentOffset方法
- (void)setContentOffset:(CGPoint)contentOffset{ [super setContentOffset:contentOffset]; CGFloat y = contentOffset.y; if(self.type == LolitaTableViewTypeMain){ // main类型 CGFloat stayPosition = self.tableHeaderView.frame.size.height; // 默认停留的位置 if ([self.delegate_StayPosition respondsToSelector:@selector(lolitaTableViewHeightForStayPosition:)]) { stayPosition = [self.delegate_StayPosition lolitaTableViewHeightForStayPosition:self]; // 获取到停留的位置 } if(self.canScroll == YES){ if(y > stayPosition){ contentOffset.y = stayPosition; [super setContentOffset:contentOffset]; self.canScroll = NO; // 发送通知,主类不可滚动 [[NSNotificationCenter defaultCenter] postNotificationName:kScrollStopNotificationName object:self userInfo:nil]; }else{ // main正常滚动 [super setContentOffset:contentOffset]; } }else{ // main禁止滚动 contentOffset.y = stayPosition; [super setContentOffset:contentOffset]; } }else if(self.type == LolitaTableViewTypeSub){ // sub类型 if(self.canScroll == YES){ if(y < 0){ contentOffset.y = 0; [super setContentOffset:contentOffset]; self.canScroll = NO; // 发送通知,子类不可滚动 [[NSNotificationCenter defaultCenter] postNotificationName:kScrollStopNotificationName object:self userInfo:nil]; }else{ // sub正常滚动 [super setContentOffset:contentOffset]; } }else{ // sub禁止滚动 contentOffset.y = 0; [super setContentOffset:contentOffset]; } }else{ [super setContentOffset:contentOffset]; }}
4、通知处理
- (void)scrollStop:(NSNotification *)notification{ LolitaTableView *table = notification.object; // 把其他所有的sub都移动到顶部 if (table.type == LolitaTableViewTypeSub && self.type == LolitaTableViewTypeSub) { [self setContentOffset:CGPointZero]; } if(self != table){ // 发送通知的table和当前self不是同一个时,则需要滚动 self.canScroll = YES; }}
使用
1、父类tableView
@property (strong ,nonatomic) LolitaTableView *mainTable;// 初始化父类列表-(LolitaTableView *)mainTable{ if (_mainTable==nil) { _mainTable = [[LolitaTableView alloc] initWithFrame:CGRectMake(0, 64, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height-64) style:UITableViewStyleGrouped]; _mainTable.delegate = self; _mainTable.dataSource = self; _mainTable.delegate_StayPosition = self; // 悬停代理 _mainTable.tableFooterView = [UIView new]; _mainTable.showsVerticalScrollIndicator = NO; _mainTable.type = LolitaTableViewTypeMain; // 列表类型 } return _mainTable;}注:需要将子列表加到列表上,最好是最后一个section的cell上,这样比较灵活;其他位置也可以添加,主要是需要配合悬停的位置使用// 实现悬停代理// !!!: 悬停的位置-(CGFloat)lolitaTableViewHeightForStayPosition:(LolitaTableView *)tableView{ // 悬停在第3个secion.y处 return [tableView rectForSection:2].origin.y;}
2、子类列表
-(LolitaTableView *)table{ if (_table==nil) { _table = [[LolitaTableView alloc] initWithFrame:CGRectZero]; _table.delegate = self; _table.dataSource = self; _table.showsVerticalScrollIndicator = NO; _table.tableFooterView = [UIView new]; _table.type = LolitaTableViewTypeSub; // 除了类型要设置为子类,用法和系统类型一样 } return _table;}
Demo地址
阅读全文
0 0
- iOS UITableView的嵌套和sectionHeaderView悬停的解决方案
- iOS sectionHeaderView的做法
- 下拉刷新和UITableView的sectionHeaderView冲突的问题
- UITableView的headerView悬停解决方案
- IOS TableViewStylePlain header 悬停的解决方案
- UITableView的section header view悬停和取消的方法
- UITableView的使用(UITableViewCell\section页眉\section页脚复用、sectionHeaderView点击效果)
- UITableView的使用(UITableViewCell\section页眉\section页脚复用、sectionHeaderView点击效果)
- UITableView的分区头 悬停问题
- iOS中表格(UITableView)嵌套表格的简单实现
- IOS开发~UISCrollView与UITableView嵌套使用终极解决方案
- IOS开发~UISCrollView与UITableView嵌套使用终极解决方案
- iOS开发:UISCrollView与UITableView嵌套使用终极解决方案
- IOS开发~UISCrollView与UITableView嵌套使用终极解决方案
- 让UITableView的section header view不悬停的方法
- 让UITableView的section header view不悬停的方法
- 让UITableView的headerview不悬停的方法
- 去掉UITableView的section的粘性,使其不会悬停
- 中国GDG Google I/O之行所见:带回国际创新风采,做中国开发者连接世界的桥梁
- D3D11的颜色处理
- 马上加入 | 今天下午4:00线上训练营课程I/O新功能特辑
- 官方详细介绍Android Studio 3.0 Canary 1
- #io17#官方总结:助力开发者在各个平台上打造最佳体验
- iOS UITableView的嵌套和sectionHeaderView悬停的解决方案
- Android 兼容性 | Google Play 开发者 FAQ 特别版
- 邀请函 | Google Play 成长之星 Pizza Night x 游戏茶馆
- #io17# Android中的新功能:Android O和其他发布
- #io17# 发布Android Things Developer Preview 4
- 谷歌开发者 - CSDN博客
- Android免安装应用对所有开发者开放
- 马上报名 | Google Play 开发者训练营5月线上课程I/O特辑
- 更好用!I/O大会公布了这些Google Play管理中心新功能