美文网首页
横向滑动懒加载效果+升级版

横向滑动懒加载效果+升级版

作者: 宙斯YY | 来源:发表于2018-09-19 11:05 被阅读43次

    一.基础版本

    导航条置顶样式


    1.jpeg

    这里导航条和内容列表是分离的,所以在UI处理上也可以分离,只要实现懒加载效果就行。
    思路:核心点是两个,UIViewController childViewController的使用;scrollview滑动结束后加载数据。

    1.主控制器中添加子控制器
    UIScrollView * scrollview=[[UIScrollView alloc]initWithFrame:CGRectMake(0, 50, SDScreenWidth, SDScreenHeight-50)];
        int index=0;
        NSMutableArray * vcnames=[NSMutableArray arrayWithObjects:@"1",@"2",nil];
        scrollview.contentSize=CGSizeMake(SDScreenWidth*vcnames.count, scrollview.height);
        for(int i=0;i<vcnames.count;i++)
        {
            NSString * vcname=vcnames[i];
            UIViewController * vc=[[NSClassFromString(vcname) alloc]init];
            [self addChildViewController:vc];
            if(i==index)
            {
                vc.view.frame=CGRectMake(index*scrollview.width, 0, scrollview.width, scrollview.height);
                [scrollview addSubview:vc.view];
                scrollview.contentOffset=CGPointMake(index*scrollview.width, 0);
            }
        }
    
    2.实现懒加载效果(滑动结束后加载页面+按钮点击结束后加载页面)
    -(void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
    {
        CGFloat width=scrollView.width;
        CGFloat height=scrollView.height;
        index=scrollView.contentOffset.x/width;
        UIViewController * vc=self.childViewControllers[index];
        if(![vc isViewLoaded])
        {
            vc.view.frame=CGRectMake(width*index, 0, width, height);
            [scrollView addSubview:vc.view];
        }
    }
    
    -(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
    {
        [self scrollViewDidEndDecelerating:scrollView];
    }
    
    3.处理点击引导条处理
    -(void)tap:(UIButton*)btn
    {
        index=btn.tag;
        [scrollview setContentOffset:CGPointMake(index*scrollview.width, 0) animated:YES];
    }
    

    二.升级版本

    导航条置顶样式


    2.jpeg

    这里导航条和内容列表是联动的,且上滑时导航条卡住不动。
    思路:整体是一个主UITableView,每个栏目是子控制器的内部UITableView。
    问题:当导航条不在顶部的时候,滑动列表时子列表跟随主列表滑动;当导航条到达顶部时,滑动列表时子列表滑动,主列表不滑动。

    1.建立主容器类和子容器类ContainerNestViewController,ContainerNestSubViewController。

    ContainerNestViewController.h

    @interface ContainerNestMainTableView:UITableView<UIGestureRecognizerDelegate>
    @end
    
    @interface ContainerNestViewController : BaseViewController
    
    @property(nonatomic,assign) NSInteger currentPage;
    @property(nonatomic,assign) BOOL subcansc;
    @property(nonatomic,assign) BOOL maincansc;
    
    //主TableView
    @property(nonatomic,weak) ContainerNestMainTableView * mainTableView;
    //子控制器导航条
    @property(nonatomic,weak) ContainerNestNavView * navsubControllerView;
    //子控制器导航条-navView
    @property(nonatomic,weak) UIScrollView * navView;
    //子控制器导航条-sliderview
    @property(nonatomic,weak) UIView * sliderview;
    //子控制器TableViewCell
    @property(nonatomic,weak) UITableViewCell * subContentView;
    //子控制器TableViewCell-scrollview
    @property(nonatomic,weak) UIScrollView * scrollview;
    
    @property(nonatomic,strong)NSArray<ContainerNestSubViewController*> * controllers;
    
    //刷新子控制器滑动
    -(void)refreshScrollviewIndex;
    //刷新子控制器导航条
    -(void)refreshNavScrollviewIndex;
    

    ContainerNestViewController.m

    @implementation ContainerNestMainTableView
    -(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
    {
        return YES;
    }
    
    @end
    
    @interface ContainerNestViewController ()<UIScrollViewDelegate,UIGestureRecognizerDelegate>
    
    @end
    
    @implementation ContainerNestViewController
    
    #pragma mark - Setter and Getter
    
    -(void)setControllers:(NSArray<ContainerNestSubViewController *> *)controllers
    {
        _controllers=controllers;
        for(int i=0;i<controllers.count;i++)
        {
            ContainerNestSubViewController * subvc=controllers[i];
            subvc.block = ^(UIScrollView *scrollview, BOOL isUpping) {
                [self controlSubScrollView:scrollview];
                self.mainTableView.bounces=isUpping;
            };
        
            subvc.block2 = ^(BOOL isDrag) {
                self.scrollview.scrollEnabled=!isDrag;
            };
            [self addChildViewController:subvc];
        }
    }
    
    -(void)setMainTableView:(ContainerNestMainTableView *)mainTableView
    {
        _mainTableView=mainTableView;
        _mainTableView.bounces=NO;
        _mainTableView.showsVerticalScrollIndicator=NO;
        _mainTableView.showsHorizontalScrollIndicator=NO;
        [self.mainTableView registerNib:[UINib nibWithNibName:@"ContainerNestContentTableViewCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"containerNestContentTableViewCell"];
    }
    
    -(ContainerNestNavView *)navsubControllerView
    {
        ContainerNestNavView * view=[ContainerNestNavView shareView];
        view.currentPage=self.currentPage;
        view.controllers=self.controllers;
        view.block = ^(NSInteger btnTag) {
            self.currentPage=btnTag;
            [self refreshScrollviewIndex];
            [self refreshNavScrollviewIndex];
        };
        self.navView=view.navView;
        self.sliderview=view.sliderview;
        return view;
    }
    
    -(UITableViewCell *)subContentView
    {
        ContainerNestContentTableViewCell * contentcell=[self.mainTableView dequeueReusableCellWithIdentifier:@"containerNestContentTableViewCell"];
        contentcell.selectionStyle=UITableViewCellSelectionStyleNone;
        contentcell.contentScrollView.delegate=self;
        self.scrollview=contentcell.contentScrollView;
        contentcell.contentScrollView.contentSize=CGSizeMake(SDScreenWidth*self.controllers.count,self.view.height);
        return contentcell;
    }
    
    #pragma  mark - 解决手势冲突+滑动处理
    
    -(void)controlSubScrollView:(UIScrollView*)scrollview
    {
        if (self.maincansc) {
            scrollview.contentOffset = CGPointZero;
        }else
        {
            if (scrollview.contentOffset.y <= 0) {
                self.maincansc = YES;
                self.subcansc = NO;
            }else if (scrollview.contentOffset.y > 0) {
                self.maincansc = NO;
                self.subcansc = YES;
            }
        }
        
    }
    
    -(void)scrollViewDidScroll:(UIScrollView *)scrollView
    {
        CGRect navRect=[self.mainTableView rectForSection:1];
        if(self.mainTableView.contentOffset.y>=navRect.origin.y)
        {
            if(self.maincansc)
            {
                self.maincansc = NO;
                self.subcansc = YES;
                self.mainTableView.contentOffset=CGPointMake(0, navRect.origin.y);
            }
        }else
        {
            if(self.maincansc ==NO&&self.subcansc ==YES)
            {
                self.subcansc = YES;
                self.maincansc = NO;
                self.mainTableView.contentOffset=CGPointMake(0, navRect.origin.y);
            }else
            {
                self.subcansc = NO;
                self.maincansc = YES;
            }
        }
    }
    
    
    -(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
    {
        if(scrollView==self.scrollview)
        {
            [self scrollViewDidEndScrollingAnimation:scrollView];
        }
        
    }
    
    -(void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
    {
        if(scrollView==self.scrollview)
        {
            self.currentPage =(int)(self.scrollview.contentOffset.x/SDScreenWidth);
            [self refreshScrollviewIndex];
        }
    }
    
    
    -(void)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         refreshScrollviewIndex
    {
        UIViewController * vc = self.childViewControllers[self.currentPage];
        if(![vc isViewLoaded])
        {
            vc.view.frame=CGRectMake(self.scrollview.width*self.currentPage, 0, self.scrollview.width, self.scrollview.height);
            [self.scrollview addSubview:vc.view];
        }
        [self.scrollview setContentOffset:CGPointMake(self.currentPage*SDScreenWidth, 0) animated:YES];
        [self refreshNavScrollviewIndex];
    }
    
    -(void)refreshNavScrollviewIndex
    {
        for(int i=0;i<self.navView.subviews.count;i++)
        {
            UIView * subview=self.navView.subviews[i];
            if([subview isKindOfClass:UIButton.class])
            {
                UIButton * btn=(UIButton*)subview;
                if(btn.tag==self.currentPage)
                {
                    btn.selected=YES;
                    self.sliderview.centerX=btn.centerX;
                    [self.navView scrollRectToVisible:btn.frame animated:YES];
                    
                }else
                {
                    btn.selected=NO;
                }
            }
        }
    }
    

    ContainerNestSubViewController.h

    //isUpping-滑动方向
    typedef void(^ContainerNestSubViewControllerBlock)(UIScrollView*scrollview,BOOL isUpping);
    typedef void(^ContainerNestSubViewControllerBlock2)(BOOL isDrag);
    
    @interface ContainerNestSubViewController : BaseViewController
    
    @property(nonatomic,copy) ContainerNestSubViewControllerBlock block;
    @property(nonatomic,copy) ContainerNestSubViewControllerBlock2 block2;
    
    @end
    
    

    ContainerNestSubViewController.m

    @interface ContainerNestSubViewController ()<UIScrollViewDelegate>
    {
        CGFloat oldY;
    }
    @end
    
    @implementation ContainerNestSubViewController
    
    -(void)addSubViews
    {
        [super addSubViews];
    }
    
    -(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
    {
        if(_block2&&self.baseTableview)
        {
            _block2(YES);
            oldY = scrollView.contentOffset.y;
        }
        
    }
    
    -(void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
    {
        if(_block2&&self.baseTableview)
        {
            _block2(NO);
        }
    }
    
    -(void)scrollViewDidScroll:(UIScrollView *)scrollView
    {
       //传递滑动方向,上拉无弹簧效果,下拉有弹簧效果(可下拉加载)
        if(_block&&self.baseTableview)
        {
            if (scrollView.contentOffset.y>oldY) {
                _block(scrollView,NO);
            }
            else{
                _block(scrollView,YES);
            }
        }
    }
    
    2.建立导航条ContainerNestNavView和ContainerNestContentTableViewCell(ScrollView)

    ContainerNestNavView.h

    typedef void(^ContainerNestNavViewBlock)(NSInteger btnTag);
    
    @interface ContainerNestNavView : UIView
    
    @property(nonatomic,assign) NSInteger currentPage;
    @property(nonatomic,weak) UIScrollView * navView;
    @property(nonatomic,weak) UIView * sliderview;
    
    @property(nonatomic,strong)NSArray<ContainerNestSubViewController*> * controllers;
    
    @property(nonatomic,copy)ContainerNestNavViewBlock block;
    
    +(instancetype)shareView;
    

    ContainerNestNavView.m

    @interface ContainerNestNavView()
    
    @end
    
    @implementation ContainerNestNavView
    
    +(instancetype)shareView
    {
       return [[self alloc]initWithFrame:CGRectMake(0, 0, SDScreenWidth,ContainerNestNavViewHeight)];
    }
    
    
    -(instancetype)initWithFrame:(CGRect)frame
    {
        if(self=[super initWithFrame:frame])
        {
            self.backgroundColor=[UIColor whiteColor];
            UIView * sepv=[[UIView alloc]initWithFrame:CGRectMake(0, 39, SDScreenWidth, 1)];
            sepv.backgroundColor=SDColor(246, 246, 246);
            [self addSubview:sepv];
            UIScrollView * navs=[[UIScrollView alloc]initWithFrame:CGRectMake(0, 0, SDScreenWidth, 39)];
            navs.showsVerticalScrollIndicator=NO;
            navs.showsHorizontalScrollIndicator=NO;
            [self addSubview:navs];
            UIView * sliderview=[[UIView alloc]initWithFrame:CGRectMake(0, 37, 20, 2)];
            sliderview.backgroundColor=ThemeColor;
            [navs addSubview:sliderview];
            self.sliderview=sliderview;
            self.navView=navs;
        }
        return self;
    }
    
    
    -(void)setControllers:(NSArray<ContainerNestSubViewController *> *)controllers
    {
        _controllers=controllers;
        CGFloat sumTextWidth=0.0;
        for(int i=0;i<self.controllers.count;i++)
        {
            ContainerNestSubViewController * subvc=self.controllers[i];
            CGFloat textWidth=[subvc.title widthForText:SDFontOf14]+30;
            UIButton * btn=[[UIButton alloc]initWithFrame:CGRectMake(sumTextWidth, 0, textWidth, 39)];
            btn.tag=i;
            btn.titleLabel.font=SDFontOf14;
            [btn setTitleColor:SDColor(63, 63, 63) forState:UIControlStateNormal];
            [btn setTitleColor:ThemeColor forState:UIControlStateSelected];
            [btn setTitle:subvc.title forState:UIControlStateNormal];
            [[btn rac_signalForControlEvents:UIControlEventTouchUpInside]subscribeNext:^(__kindof UIControl * _Nullable x) {
                    if(self.block)
                {
                    self.block(x.tag);
                }
            }];
            [self.navView addSubview:btn];
            if(i==self.currentPage)
            {
                btn.selected=YES;
                self.sliderview.centerX=btn.centerX;
            }
            sumTextWidth+=textWidth;
        }
        self.navView.contentSize=CGSizeMake(sumTextWidth, self.navView.height);
    }
    
    

    ContainerNestContentTableViewCell.h

    @interface ContainerNestContentTableViewCell : UITableViewCell
    @property (weak, nonatomic) IBOutlet UIScrollView *contentScrollView;
    @end
    

    ContainerNestContentTableViewCell.m

    @interface ContainerNestContentTableViewCell()
    @end
    
    @implementation ContainerNestContentTableViewCell
    
    - (void)awakeFromNib {
        [super awakeFromNib];
        self.contentScrollView.pagingEnabled=YES;
    }
    
    
    3.应用

    主控制器
    StoreViewController.h

    @interface StoreViewController : ContainerNestViewController
    @property(strong, nonatomic) ContainerNestMainTableView *tableview;
    @end
    

    StoreViewController.m

    #pragma mark - UITableView数据源和代理
    
    -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
    {
        return 2;
    }
    
    -(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
    {
        if(section==0)
        {
            return 0;
        }else
        {
            return 40;
        }
        
    }
    
    -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if(indexPath.section==0)
        {
           //自定义Cell高度
        }else
        {
            return self.view.height;
        }
        return 0.0;
    }
    
    -(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
    {
        if(section==1)
        {
            return self.navsubControllerView;
        }
        return [[UIView alloc]init];
    }
    
    
    -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        if(section==0)
        {
            //自定义Cell数目
        }else if(section==1)
        {
            return 1;
        }
        return 0;
    }
    
    
    -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
    
        if(indexPath.section==0)
        {
              //自定义Cell
        }
        else if(indexPath.section==1)
        {
            return self.subContentView;
        }
        return nil;
    }
    

    子控制器就是继承ContainerNestSubViewController的普通控制器
    StoreContentViewController_sub.h

    @interface StoreContentViewController_sub : ContainerNestSubViewController
    @end
    

    相关文章

      网友评论

          本文标题:横向滑动懒加载效果+升级版

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