iOS开发(JXPagerView、JXCategoryView)遇到的问题及解决办法


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

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

@protocol JXPagerViewListViewDelegate 

/**
 返回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)遇到的问题及解决办法)