最近作項目遇到要實現如微博我的詳情頁的滑動效果,經過查找資料最終完成了GKPageScrollView,可實現如微博、抖音、網易雲等我的詳情頁的滑動效果。git
該庫的實現方式參考了JXPagingView,效果可能更好更全點。github
說明 | 效果圖 |
---|---|
微博我的主頁 |
![]() |
網易雲歌手頁 |
![]() |
抖音我的主頁 |
![]() |
主頁下拉刷新 |
![]() |
列表下拉刷新 |
![]() |
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);
}
}
}
複製代碼
具體是實現還須要看代碼瞭解bash
##使用 一、建立GKPageScrollView,並實現其代理方法ui
// 一、建立GKPageScrollView
self.pageScrollView = [[GKPageScrollView alloc] initWithDelegate:self];
self.pageScrollView.frame = self.view.bounds;
[self.view addSubview:self.pageScrollView];
// 二、實現代理方法
#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;
}
複製代碼
二、在listView中實現GKPageListViewDelegate代理方法,listView能夠是UIView,UIViewControllerspa
#pragma mark - GKPageListViewDelegate
- (UIScrollView *)listScrollView {
return self.tableView;
}
- (void)listViewDidScrollCallback:(void (^)(UIScrollView * _Nonnull))callback {
self.listScrollViewScrollBlock = callback;
}
複製代碼
這樣就可實現仿微博我的主頁的效果了。3d
三、若是想要實現導航欄漸變、頭圖下拉放大效果,須要在下面方法中作處理代理
- (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];
}
複製代碼
項目地址:GKPageScrollViewcode
另外推薦下個人圖片瀏覽器GKPhotoBrowsercdn