前言
最近做專案遇到要實現如微博個人詳情頁的滑動效果,通過查詢資料最終完成了GKPageScrollView,可實現如微博、抖音、網易雲等個人詳情頁的滑動效果。
該庫的實現方式參考了JXPagingView,效果可能更好更全點。
主要功能
- 支援上下滑動、左右滑動,手勢返回等
- 支援如UITableView的sectionView的懸停效果
- 支援多種分頁控制元件,如JXCategory,WMPageController等
- 可實現導航欄顏色漸變、頭圖下拉放大等效果
- 支援主頁、列表頁下拉重新整理,上拉載入
效果圖
說明 | 效果圖 |
---|---|
微博個人主頁 | |
網易雲歌手頁 | |
抖音個人主頁 | |
主頁下拉重新整理 | |
列表下拉重新整理 |
實現
GKPageScrollView的結構為UITableView + tableHeaderView + 分頁控制元件。主要是在UIScrollview的代理方法scrollViewDidScroll方法中做處理,判斷是tableView滑動,還是listView滑動。主要程式碼如下:
// 處理子頁面listScrollView滑動
- (void)listScrollViewDidScroll:(UIScrollView *)scrollView {
// 如果禁止listScrollview滑動,則固定其位置
if (!self.isListCanScroll) {
scrollView.contentOffset = CGPointZero;
}
// 獲取listScrollview偏移量
CGFloat offsetY = scrollView.contentOffset.y;
// listScrollView下滑至offsetY小於0,禁止其滑動,讓mainTableView可下滑
if (offsetY <= 0) {
self.isMainCanScroll = YES;
self.isListCanScroll = NO;
scrollView.contentOffset = CGPointZero;
scrollView.showsVerticalScrollIndicator = NO;
}else {
if (self.isListCanScroll) {
scrollView.showsVerticalScrollIndicator = YES;
}
}
}
複製程式碼
// 處理mainTableView滑動
- (void)mainScrollViewDidScroll:(UIScrollView *)scrollView {
// 獲取mainScrollview偏移量
CGFloat offsetY = scrollView.contentOffset.y;
// 臨界點
CGFloat criticalPoint = [self.mainTableView rectForSection:0].origin.y - self.ceilPointHeight;
// 根據偏移量判斷是否上滑到臨界點
if (offsetY >= criticalPoint) {
self.isCriticalPoint = YES;
}else {
self.isCriticalPoint = NO;
}
if (self.isCriticalPoint) {
// 上滑到臨界點後,固定其位置
scrollView.contentOffset = CGPointMake(0, criticalPoint);
self.isMainCanScroll = NO;
self.isListCanScroll = YES;
}else {
if (self.isMainCanScroll) {
// 未達到臨界點,mainScrollview可滑動,需要重置所有listScrollView的位置
[[self.delegate listViewsInPageScrollView:self] enumerateObjectsUsingBlock:^(id<GKPageListViewDelegate> _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
UIScrollView *listScrollView = [obj listScrollView];
listScrollView.contentOffset = CGPointZero;
listScrollView.showsVerticalScrollIndicator = NO;
}];
}else {
// 未到達臨界點,mainScrollview不可滑動,固定其位置
scrollView.contentOffset = CGPointMake(0, criticalPoint);
}
}
}
複製程式碼
具體是實現還需要看程式碼瞭解
##使用 1、建立GKPageScrollView,並實現其代理方法
// 1、建立GKPageScrollView
self.pageScrollView = [[GKPageScrollView alloc] initWithDelegate:self];
self.pageScrollView.frame = self.view.bounds;
[self.view addSubview:self.pageScrollView];
// 2、實現代理方法
#pragma mark - GKPageScrollViewDelegate
- (UIView *)headerViewInPageScrollView:(GKPageScrollView *)pageScrollView {
return self.headerView;
}
- (UIView *)pageViewInPageScrollView:(GKPageScrollView *)pageScrollView {
return self.pageView;
}
- (NSArray<id<GKPageListViewDelegate>> *)listViewsInPageScrollView:(GKPageScrollView *)pageScrollView {
return self.childVCs;
}
複製程式碼
2、在listView中實現GKPageListViewDelegate代理方法,listView可以是UIView,UIViewController
#pragma mark - GKPageListViewDelegate
- (UIScrollView *)listScrollView {
return self.tableView;
}
- (void)listViewDidScrollCallback:(void (^)(UIScrollView * _Nonnull))callback {
self.listScrollViewScrollBlock = callback;
}
複製程式碼
這樣就可實現仿微博個人主頁的效果了。
3、如果想要實現導航欄漸變、頭圖下拉放大效果,需要在下面方法中做處理
- (void)mainTableViewDidScroll:(UIScrollView *)scrollView {
// 導航欄顯隱
CGFloat offsetY = scrollView.contentOffset.y;
// 0-200 0
// 200 - KDYHeaderHeigh - kNavBarheight 漸變從0-1
// > KDYHeaderHeigh - kNavBarheight 1
CGFloat alpha = 0;
if (offsetY < 200) {
alpha = 0;
}else if (offsetY > (kDYHeaderHeight - kNavBarHeight)) {
alpha = 1;
}else {
alpha = (offsetY - 200) / (kDYHeaderHeight - kNavBarHeight - 200);
}
self.gk_navBarAlpha = alpha;
self.titleView.alpha = alpha;
// 頭圖下拉放大
[self.headerView scrollViewDidScroll:offsetY];
}
複製程式碼
最後
專案地址:GKPageScrollView
另外推薦下我的圖片瀏覽器GKPhotoBrowser