美文网首页
关于多tablview上下拉升的效果实现

关于多tablview上下拉升的效果实现

作者: 养个小东西 | 来源:发表于2018-09-27 20:33 被阅读8次

    0 最近因为项目的原因需要实现微博多tablview上下拉升的特效,所以在网上找了个框架:AXStretchableHeaderTabViewController ,

    具体实现效果如下

    在使用这个框架的时候是个很蛋疼的过程

    1、必须要先计算出头部绿色视图的高度,才能创建头部视图和下面两个ViewController,否则上下拉伸会有问题

    后来仔细阅读了这个框架的源码后,我就自己写了一个LPPZStretchViewController,精简了很多代码,而且在使用更加便捷

    实现的思路

    1、在LPPZStretchViewController中,先创建UIScrollView*mainScrollView

      self.mainScrollView =({

            UIScrollView* mainScrollView = [[UIScrollViewalloc]init];

            mainScrollView.delegate=self;

            mainScrollView.backgroundColor = [UIColor yellowColor];

            [self.view addSubview:mainScrollView];

            mainScrollView.pagingEnabled=YES;

            mainScrollView.contentSize=CGSizeMake(UI_SCREEN_WIDTH*2,0);

            mainScrollView.frame=CGRectMake(0,0,UI_SCREEN_WIDTH,UI_SCREEN_HEIGHT);

            mainScrollView;

        });

    2、然后再创建继承自LPPZStretchHeaderView的header,(在LPPZStretchHeaderView中会有一些其他的处理,主要是关于事件传递的处理,在文章的最后我会写)

        _headerView = [[LPPZStretchHeaderView alloc] init];

    //重要的地方。_headerView不是添加到mainScrollView上哦

        [self.view addSubview:_headerView];

        _headerView.backgroundColor = [UIColor greenColor];

        [_headerView mas_makeConstraints:^(MASConstraintMaker *make) {

            make.left.top.right.equalTo(self.view);

            self.headerViewHeightConstraint=  make.height.mas_equalTo(self.MaxHeaderViewHeight);

        }];

    注意:1、self.MaxHeaderViewHeight是headerView可拉伸的最大长度  

              2、self.MinHeaderViewHeight是headerView可拉伸的最短长度

    3、然后在创建中间黄色的类别条LPPZStretchTabBarView

     self.tabBarView = ({

            LPPZStretchTabBarView *tabBarView = [[LPPZStretchTabBarView alloc] init];

            [self.viewaddSubview:tabBarView];

            tabBarView.backgroundColor = [UIColor yellowColor];

            tabBarView.titles=@[@"精选",@"热门"];

            [tabBarViewmas_makeConstraints:^(MASConstraintMaker *make) {

                make.left.right.equalTo(self.view);

                make.height.mas_equalTo(KtabBarHeigh);

                make.top.equalTo(self.headerView.mas_bottom);

            }];

            tabBarView;

        });

    4、然后这创建自定义的LPPZListViewController,并且LPPZListViewController包含有属性tableView的UITableView    ,主要是方便取出LPPZListViewController中的tableView,LPPZListViewController的视图是在mainScrollView伤的

        LPPZListViewController * vc1 = [[LPPZListViewController alloc] init];

        LPPZListViewController * vc2 = [[LPPZListViewController alloc] init];

           NSIndexPath * indexPath = [NSIndexPath indexPathForRow:0 inSection:0];

    //y是设置tableView的头部边距,

            CGFloat y = KtabBarHeigh + self.MaxHeaderViewHeight;

            [self addChildViewController:vc1];

            [self.mainScrollView addSubview:vc1.view];

            UITableView* tableView  = [vc1 valueForKey:@"tableView"];

    //监听tableView的偏移量的变化,

            [tableView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:nil];

            vc1.view.frame = CGRectMake(0 *UI_SCREEN_WIDTH, 0,UI_SCREEN_WIDTH,UI_SCREEN_HEIGHT);

            tableView.contentInset=UIEdgeInsetsMake(y,0,0,0);

            [tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:NO];

    [self addChildViewController:vc2];

            [self.mainScrollViewaddSubview:vc2.view];

    UITableView* tableView2  = [vc2 valueForKey:@"tableView"];

    //监听tableView的偏移量的变化,

            [tableView2 addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:nil];

     vc2.view.frame = CGRectMake(0 *UI_SCREEN_WIDTH, 0,UI_SCREEN_WIDTH,UI_SCREEN_HEIGHT);

            tableView2.contentInset=UIEdgeInsetsMake(y,0,0,0);

            [tableView2 scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:NO];

    5、监听tableview的偏移量,重新设置headerView的高度,以及ListViewController在mainScrollView的frame

    -(void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void*)context{

        if([keyPathisEqualToString:@"contentOffset"]) {

    //计算tableView向上滑动的距离,从而设置headView的高度,当headView高度变短时,headView遮盖tableView的高度也就小了,

            CGFloat headerViewHeight = self.MaxHeaderViewHeight - (self.selectedScrollView.contentOffset.y + self.selectedScrollView.contentInset.top) -20;

    //headView的高度不能小于self.MinHeaderViewHeight

            if(headerViewHeight <=self.MinHeaderViewHeight) {

                headerViewHeight =self.MinHeaderViewHeight;

            }

            self.headerViewHeightConstraint.mas_equalTo(headerViewHeight);

            !self.headerViewHeightChangeBlock ?: self.headerViewHeightChangeBlock(headerViewHeight);

        }

    }

    结尾:在LPPZStretchHeaderView需要重写- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event方法

    - (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event{

        UIView* targetView = [superhitTest:pointwithEvent:event];

    //当相应事件点击的View是LPPZStretchHeaderView是,则返回nil,这样根据iOS事件传递的机制,事件会传递给LPPZStretchHeaderView的下面的mainScrollView,这样手机放在LPPZStretchHeaderView上也可以做到上下互动的效果

        if(targetView ==self) {

            returnnil;

        }

       if(targetView.userInteractionEnabled==YES) {

            NSLog(@"123godlike");

            returntargetView;

        }

    关于LPPZStretchViewControllerd,我已经上传到了github上,LPPZStretchViewController,希望大家提出优化的意见

    相关文章

      网友评论

          本文标题:关于多tablview上下拉升的效果实现

          本文链接:https://www.haomeiwen.com/subject/xhryoftx.html