iOS開發(JXPagerView、JXCategoryView)遇到的問題及解決辦法


一、 當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;
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容