美文网首页PerhapYS的Swift学习日记iOS一点通
iOS开发(JXPagerView、JXCategoryView

iOS开发(JXPagerView、JXCategoryView

作者: cocoaCoffee | 来源:发表于2019-07-18 17:03 被阅读0次

    一、 当listView内部持有的UIScrollView或UITableView或UICollectionView,滑动UIScrollView或UITableView或UICollectionView会瞬间置顶

    这个主要是分页的子控制器里面的代理协议方法listViewDidScrollCallback没有把JXPagerViewListView的scrollView和UIScrollView或UITableView或UICollectionView的scrollView关联起来导致的,一般分页的子控制器都要实现如下三个方法

    @protocol JXPagerViewListViewDelegate <NSObject>
    
    /**
     返回listView。如果是vc包裹的就是vc.view;如果是自定义view包裹的,就是自定义view自己。
    
     @return UIView
     */
    - (UIView *)listView;
    
    /**
     返回listView内部持有的UIScrollView或UITableView或UICollectionView
     主要用于mainTableView已经显示了header,listView的contentOffset需要重置时,内部需要访问到外部传入进来的listView内的scrollView
    
     @return listView内部持有的UIScrollView或UITableView或UICollectionView
     */
    - (UIScrollView *)listScrollView;
    
    
    /**
     当listView内部持有的UIScrollView或UITableView或UICollectionView的代理方法`scrollViewDidScroll`回调时,需要调用该代理方法传入的callback
    
     @param callback `scrollViewDidScroll`回调时调用的callback
     */
    - (void)listViewDidScrollCallback:(void (^)(UIScrollView *scrollView))callback;
    

    @protocol 协议方法必须实现,没写或没写全会直接崩溃的而想要解决上面的bug可以这样写

    // 定义一个block回调
    @property (nonatomic, copy) void(^scrollCallback)(UIScrollView *scrollView);
    
    // 滑动的代理事件,滑动的时候就会调用这个回调,把scrollView传进去
    - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
        self.scrollCallback(scrollView);
    }
    
    // 再把listViewDidScrollCallback的scrollView关联起来
    - (void)listViewDidScrollCallback:(void (^)(UIScrollView *))callback {
        self.scrollCallback = callback;
    }
    
    修改后的效果图

    二、 当listView内部持有的UIScrollView或UITableView弹簧效果与下拉刷新冲突

    在初始化JXPagerView的时候禁用了UIScrollView或UITableView弹簧效果(bounces)即可

            _pagerView = [[JXPagerView alloc]initWithDelegate:self];
            _pagerView.mainTableView.bounces = NO;
    

    2022年1月15 更新
    如果上面的方法没用可以将JXPagerView换成JXPagerListRefreshView, 作者的Demo就是用的JXPagerListRefreshView

    _pagerView = [[JXPagerListRefreshView alloc]initWithDelegate:self];
    

    三、 顶部的View高度改变不适配问题

    • 一开始没改变之前的顶部View高度不对,可以在返回顶部View的代理方法里面这样写
    // 我_headerView里面使用约束来布局的
    - (NSUInteger)tableHeaderViewHeightInPagerView:(JXPagerView *)pagerView
    {
        CGFloat headerH = [_headerView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
        return headerH;
    }
    
    • 点击改变_headerView高度就重新改变一下它的frame,最重要刷新一下JXPagerView
    CGFloat headerViewH = [self.headerView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
    self.headerView.frame = CGRectMake(0.f, 0.f, [UIScreen mainScreen].bounds.size.width, headerViewH);
    [self.pagerView reloadData];
    

    四、 如果滑上去顶部是一个导航栏,导航栏下面才是JXCategoryTitleView

    像这样:


    有两种方法

    • 把这个JXPagerView的约束布局在导航栏之下,下图就是这样做的,导航栏放着个搜索框,然后JXPagerView放在它之下,无论怎么滑,都是顶着导航栏的


    • 而下图JXPagerView是紧贴最顶部的,导航栏隐藏了起来


    JXPagerView滑动的时候有个代理方法可以监听它滑动,相当于scrollView的scrollViewDidScroll方法,就是 - (void)mainTableViewDidScroll:(UIScrollView *)scrollView,当然你要在分页子控制器里面写好那三个代理方法先
    mainTableViewDidScroll里面判断如果self.pagerView.mainTableView.contentOffset.y是否大于导航栏高度,小于就设置self.pagerView.mainTableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);,大于就设置self.pagerView.mainTableView.contentInset = UIEdgeInsetsMake(kNavBarHeight, 0, 0, 0); (kNavBarHeight为导航栏高度),这样看下效果


    这时又会出现一个bug,就是当你手离开屏幕,如果屏幕还在滑,那JXCategoryView又滑上去。这时可以用JXPagerView的一个属性
    /**
     顶部固定sectionHeader的垂直偏移量。数值越大越往下沉。
     */
    @property (nonatomic, assign) NSInteger pinSectionHeaderVerticalOffset;
    
    
       //y 轴 偏移量
        CGFloat y = self.pagerView.mainTableView.contentOffset.y;
        //需要计算的高度,kNavBarHeight为导航栏高度
        CGFloat h = kNavBarHeight;
    
        CGFloat alpha = 0;
        //超出偏移量的返回
        if (y < 0) {
            return;
        }else if (y < h) {
            self.pagerView.mainTableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
            self.pagerView.pinSectionHeaderVerticalOffset = 0;  
        }
        else{
            self.pagerView.pinSectionHeaderVerticalOffset = kNavBarHeight;
        }
    
    

    最好还是在小于导航栏高度的时候设置一下mainTableView的contentInset,要不然有时候会不顺畅和底部留空,效果如下(部分代码不展示)


    五、 适配iOS15 JXPagerView顶部会留白

    // 在定义JXPagerView的时候
    if (@available(iOS 15.0, *)) {
      _pagerView.mainTableView.sectionHeaderTopPadding = 0;
    }
    

    相关文章

      网友评论

        本文标题:iOS开发(JXPagerView、JXCategoryView

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