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

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上下拉升的效果实现)