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

如图,按照产品的需求,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);
}

复制代码
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值