tableView整体跟随手势移动的解决方案

1,977 阅读1分钟

如图,按照产品的需求,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{
    //当处于展开位置的时候要判断当前滚动的是否是tableView并且tableView是否在可滚动范围内,
    if ([scrollView isKindOfClass:[UITableView class]]&&CGRectGetMinY(scrollView.frame)>ItemViewHeight) {//让bgscro响应
        if (scrollView.contentOffset.y<0) {
            [self offsetMethod:scrollView.contentOffset.y];
        }else{
            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
        _offsetY = 0;
    }
}
-(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);
}