iOS实现B站播放页悬停交互的效果
第一种方案
采用UITableView的tableHeaderView和section header无感知切换来实现
优点: 都是系统自带属性,实现简单稳定,确保不会产生别的问题
缺点: 具有局限性,就是悬停的只有这一个整体视图的场景
实现步骤
- 首先先创建一个
headerView
- 定义一个悬停的布尔属性
isHover
,默认为YES
,在需要改变的时候去改变它. - 写一个方法,
isHover =YES
时headerView
添加为UITableView的section header
,isHover =NO
的时候设置为tableview.tableFooterView = headerView
- 设置一下
isHover
属性,调用一下方法,刷新tableview
即可
三两句话也说不太清楚,还是直接上代码吧 ~
//主要取决于什么时候去改变self.isHover的值 哔哩哔哩是在播放的时候设置悬停,暂停的时候不悬停~
self.tableView.tableHeaderView = self.isHover? [UIView new] : self.headerView;
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
return self.isHover? kHeaderHeight : 0.001;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
return self.isHover? self.headerView : [UIView new];
}
第二种方案
第二种方案的起因是第一种方案实现不了想要的效果,于是才有了第二种方案
采用UITableView的contentinsets和自定义view通过添加到不同的父视图切换来实现
优点: 实现简单暴力,易于调整
缺点: 需要计算以及处理滚动偏移的逻辑
实现步骤
- 首先先创建一个
headerView
和一个sectionHeaderView
- 定义一个悬停的布尔属性
isHover
,默认为YES
,在需要改变的时候去改变它. - 设置
tableview
的contentinsets.top
为两个view
的高度,并且设置偏移量的Y
值为负两个view
的高度 - 写一个方法,
isHover =YES
时headerView
和sectionView
添加到self.view
上(子视图移到最上层),isHover =NO
的时候,两个view添加到tableview上 - 设置一下
isHover
属性,调用一下方法,刷新tableview
即可 - 为了解决设置
section header
时,偏移一大截的问题,因为contentinsets.top
被修改了,所以不能使用这个方式,而是当成了tableview
的子视图跟随滚动而改变Y
值而已
三两句话也说不太清楚,还是直接上代码吧 ~
初始化
- (UIView *)headerView {
if (!_headerView) {
_headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, KWIDTH , kHeaderHeight)];
_headerView.backgroundColor = [UIColor blackColor];
}
return _headerView;
}
- (UIView *)sectionHeaderView {
if (!_sectionHeaderView) {
_sectionHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, KWIDTH , kSectionHeaderHeignt)];
_sectionHeaderView.backgroundColor = [UIColor orangeColor];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(20, 0, KWIDTH-40 , kSectionHeaderHeignt)];
label.textColor = [UIColor whiteColor];
label.text = @"全部评论(666)";
[_sectionHeaderView addSubview:label];
}
return _sectionHeaderView;
}
默认
[self.tableView reloadData];
self.tableView.contentInset = UIEdgeInsetsMake(kTopHeight, 0, 0, 0);
[self.tableView setContentOffset:CGPointMake(0, -kTopHeight)];
//默认悬停
hoverSwitch.on = self.isHover;
[self.view addSubview:self.headerView];
[self.view bringSubviewToFront:self.headerView];
self.headerView.frame = CGRectMake(0, kNavBarHeight, KWIDTH , kHeaderHeight);
[self.view addSubview:self.sectionHeaderView];
[self.view bringSubviewToFront:self.sectionHeaderView];
self.sectionHeaderView.frame = CGRectMake(0, CGRectGetMaxY(self.headerView.frame), KWIDTH , kSectionHeaderHeignt);
更改isHover的值
if (self.isHover) {
[self.view addSubview:self.headerView];
[self.view bringSubviewToFront:self.headerView];
self.headerView.frame = CGRectMake(0, kNavBarHeight, KWIDTH , kHeaderHeight);
[self.view addSubview:self.sectionHeaderView];
[self.view bringSubviewToFront:self.sectionHeaderView];
self.sectionHeaderView.frame = CGRectMake(0, CGRectGetMaxY(self.headerView.frame), KWIDTH , kSectionHeaderHeignt);
}else{
[self.tableView addSubview:self.headerView];
self.headerView.frame = CGRectMake(0, -kTopHeight, KWIDTH , kHeaderHeight);
}
滚动监听,设置视图交互逻辑
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
CGFloat offsetY = scrollView.contentOffset.y;
self.tableView.bounces = offsetY > 0;
if (!self.isHover) {
CGFloat tempY = offsetY + kTopHeight;
CGFloat alpha = 1 - ((kTopHeight - tempY)/kTopHeight);
UIImage *image = [UIImage createImageWithColor:[[UIColor cyanColor] colorWithAlphaComponent:alpha]];
[self.navigationController.navigationBar setBackgroundImage:image forBarMetrics:UIBarMetricsDefault];
if (offsetY >= -kTopHeight) {
if (offsetY < 0) {
[self.view addSubview:self.sectionHeaderView];
[self.view bringSubviewToFront:self.sectionHeaderView];
CGFloat sectionY = MAX(kNavBarHeight, ABS(offsetY)+kSectionHeaderHeignt);
self.sectionHeaderView.frame = CGRectMake(0,sectionY, KWIDTH , kSectionHeaderHeignt);
}
}else{
[self.tableView bringSubviewToFront:self.sectionHeaderView];
self.sectionHeaderView.frame = CGRectMake(0, CGRectGetMaxY(self.headerView.frame), KWIDTH , kSectionHeaderHeignt);
}
}else{
[self.tableView bringSubviewToFront:self.sectionHeaderView];
self.sectionHeaderView.frame = CGRectMake(0, CGRectGetMaxY(self.headerView.frame), KWIDTH , kSectionHeaderHeignt);
}
}
综合评估,我选择第二种方案实现了我想要的效果,具体查看代码 前往查看demo
未经作者授权,禁止转载
本文来自博客园,作者:CoderWGB,转载请注明原文链接:https://www.cnblogs.com/wgb1234/p/13455968.html
THE END