前言
最近做项目遇到要实现如微博个人详情页的滑动效果,通过查找资料最终完成了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