如图,按照产品的需求,tableView需要跟着手势滚动到一个高度后就不滚而是滚里面的内容,然后下拉的时候tableView也要跟着向下滚然后到背后的头部视图完全显示就不滚动。
思路是在self.view上放一个头部视图的view,然后再在self.view上放一个scrollView,scrollView不全部盖住背后的头部视图,滑动的时候造成一种折叠展开的效果。
先看一下宏定义
#define HeadViewHeight 200//头部view 的高度
#define SuspendHeight 80 //需要悬停的高度
#define ItemViewHeight 60 //itemView的高度
复制代码
UI创建过程按下不表
UIView * headVIew = [[UIView alloc]initWithFrame:CGRectMake(0, 0, IPHONE_WIDTH, HeadViewHeight)];
headVIew.backgroundColor = [UIColor redColor];
[self.view addSubview:headVIew];
_bgScro = [[UIScrollView alloc]initWithFrame:CGRectMake(0, SuspendHeight, IPHONE_WIDTH, IPHONE_HEIGHT-SuspendHeight)];
_bgScro.bounces = NO;
_bgScro.contentSize = CGSizeMake(IPHONE_WIDTH, IPHONE_HEIGHT-SuspendHeight);
[self.view addSubview:_bgScro];
itemView = [[UIView alloc]initWithFrame:CGRectMake(0, HeadViewHeight-SuspendHeight, IPHONE_WIDTH, ItemViewHeight)];
itemView.backgroundColor = [UIColor yellowColor];
_bgScro.delegate = self;
[_bgScro addSubview:itemView];
tab = [[UITableView alloc]initWithFrame:CGRectMake(0, CGRectGetMaxY(itemView.frame), IPHONE_WIDTH, IPHONE_HEIGHT-SuspendHeight-ItemViewHeight)];
tab.delegate = self;
tab.dataSource = self;
[_bgScro addSubview:tab];
复制代码
最后,所有的移动都放在 ** - (void)scrollViewDidScroll:(UIScrollView *)scrollView ** 这个方法中
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
//当处于折叠状态的时候,往下拉contentOffset只会小于0,这时候就做个动画让他滚到展开的位置就好了
if (scrollView.contentOffset.y<0) {
[UIView animateWithDuration:0.3 delay:0 usingSpringWithDamping:0.9 initialSpringVelocity:8 options:UIViewAnimationOptionCurveEaseOut animations:^{
self->itemView.center = CGPointMake(self->itemView.center.x, HeadViewHeight- SuspendHeight +ItemViewHeight/2.f);
self->tab.center = CGPointMake(self->tab.center.x, HeadViewHeight- SuspendHeight +ItemViewHeight/2.f+ItemViewHeight/2.f+CGRectGetHeight(self->tab.frame)/2.f);
} completion:nil];
return;
}
//当处于展开位置的时候要判断当前滚动的是否是tableView并且tableView是否在可滚动范围内,
if ([scrollView isKindOfClass:[UITableView class]]&&CGRectGetMinY(scrollView.frame)>ItemViewHeight) {//让bgscro响应
CGFloat delta = scrollView.contentOffset.y - _offsetY;//当前较上次scrollview滚动的offset差
[self offsetMethod:delta];
_offsetY = scrollView.contentOffset.y;//记录上次的offset
}else{//tableView响应
//当前较上次scrollview滚动的offset差
CGFloat delta = scrollView.contentOffset.y - _tabOffsetY;
if (delta<0&&scrollView.contentOffset.y<=0) {
[self offsetMethod:delta];
}
_tabOffsetY = scrollView.contentOffset.y;//记录tableView的offset
}
}
复制代码
-(void)offsetMethod:(CGFloat)delta{
CGPoint point = itemView.center;
point.y -= delta;//itemView实际应滚动的距离
if (point.y<ItemViewHeight/2.f) {
// 限制itemView的滚动y的最小值,不然会一直滚出屏幕上方
point.y=ItemViewHeight/2.f;
}else if (point.y>HeadViewHeight- SuspendHeight+ItemViewHeight/2.f){
// 同理限制itemView的滚动y的最大值,不然会一直滚出屏幕下方
point.y = HeadViewHeight- SuspendHeight +ItemViewHeight/2.f;
}
itemView.center = point;
tab.center = CGPointMake(tab.center.x, point.y+ItemViewHeight/2.f+CGRectGetHeight(tab.frame)/2.f);
}
复制代码