本文是来自@Tr2e的投稿
相信很多大佬都写过横向滑动的页面,配合各种各样自定义的XXSegmentedView实现切换的效果。这里还是要赘述一下功能,以便引出下文:
相邻页面横向滑动,实现页面的切换
点击XXSegmentedView,实现目标页面的切换
功能很简单,也很容易用UIScrollView或者UICollectionView实现,典型的效果:
看到这里,肯定有大佬问,这么平常的页面,你有啥好说的,别浪费时间好吗?大佬您先放下刀,请您再仔细看一下,两种页面在分类切换时,效果还是有细微差别的:
网易新闻:点击导航条切换时,采取不动画的方式,直接显示目标页;横向滑动则是常见的pagingEnabled动画切换
网易严选:点击导航条切换时,采取动画的切换方式,动画滚动到目标页,非相邻位置的切换同样有动画,而且会快速略过中间页面;横向滑动是常见的pagingEnabled动画切换
简单分析下,第一种是目前大部分类似产品页面采用的切换的方式,只需要设置xx...animated:(BOOL)animated中的动画参数为NO即可,这样会很好的规避采取第二种方式带来的非相邻页面快速略过中间页面这种晃眼操作的尴尬。所以我猜测这也是市面上大部分类似的页面,采用第一种方式的原因(瞎猜,大佬别打我)。但是没有人跟我一样觉得,第一种方式切换过于生硬吗?这样真的优雅吗?怎么才能让非相邻切换的页面,也是平滑过渡,看起来像相邻的一样?
作为一名认(wu)真(liao)的程序员,有了以上疑问,怎么会放任不管呢?于是便有了SPScrollPageView
SPScrollPageView
作用
让横向页面切换更流畅顺滑,解决非相邻页面切换时带来的快速略过问题
避免非相邻页面动画切换时创建非目标页面view造成的性能损耗
可直接设置初始化目标位置
支持无动画的直接页面切换
怎么使用
使用快速构建类方法创建并设置代理sp_delegate
// # How to use # CGSize screenSize = [UIScreen mainScreen].bounds.size; SPScrollPageView *pageView = [SPScrollPageView scrollPageViewWithPageCount:5 initialIndex:3 frame:(CGRect){CGPointZero,screenSize}]; pageView.sp_delegete = self; [self.view addSubview:pageView];
pageCount:总页面数
initialIndex:初始化页面所处的位置(0开始)
在代理方法中根据位置创建并返回目标View
- (UIView *)scrollPageView:(SPScrollPageView *)pageView pageForIndex:(NSInteger)index{ UIView *view = [pageView dequeuePageViewWithIndex:index]; if (!view) { if (index) { view = self.subscribed; }else{ view = self.news; } } return view; }
在代理方法中,获知当前显示的位置及View
- (void)scrollPageDidEndBounceAtPage:(UIView *)stillPage index:(NSInteger)index { NSLog(@"Current page number:%ld",index); }
在这里,你可以控制页面的刷新,更新导航条位置等操作
跳转,直接使用- (void)jumpImmediatelyToIndex:(NSInteger)index animated:(BOOL)animated;
index:目标位置 animated:是否使用动画
怎么应用
pod 'SPScrollPageView' ,'~> 0.0.3'
直接将Gayhub上项目中的SPScrollPageView文件夹拖入工程
Gayhub: SPScrollPageView 求个star ^-^
基本原理
继承自UIScrollView
设置pagingEnabled为YES,用于切换分页效果的实现
借鉴UITableview的复用机制,只创建两个Cell用于承载数据源中获取的View,避免在滚动时出现无意义的视图创建
根据位置缓存视图,管理展示视图,无需在Controller中进行冗余的处理
使用KVO监听contentOffset的变化,控制页面的复用及相关数据的更新。这里多说一点,很多情况下利用现有的UIScrollView的delegate可以更容易获悉相关状态,但是笔者没有这么做,为什么呢?假如我们过分依赖原生代理方法,一但使用者想使用相关代理方法去重新设置了delegate,那么功能一定会出现问题。
使用UIScrollView的panGestureRecognizer,结合第5条,监听处理手指拖动页面时的变化
写在最后
作为新年节后的恢复轮子,肯定有不妥或者不足的地方。如果大佬有任何意见,或者发现任何不足,希望大佬能留言或issue拍砖,野生鶸鸡在此拜谢
写在最后的最后
“愿中国青年都摆脱冷气,只是向上走,不必听自暴自弃者流的话。”