一、 當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;
}