UITableView 重用机制

最近在看这个瀑布流的项目:https://github.com/pingyourid/waterView

他自称是可以重用的,看到最后发现,这个demo的瀑布流功能做的蛮深入的。

他通过设置reuseIdentifier,视图滚动时进进出出实现视图的重复利用。区别于UITableView的UITableViewCell的重用机制,瀑布流Demo完全实现了手动控制。

UITableView虽然用了无数次,但是一直没有自习整理过他的重用机制。今天统一整理下,也方便日后实现自定义的重复功能。

重用

  1. 重用机制,主要用在UIScollView视图中,子视图会频繁上下滑动,但是自子视图的结构非常类似。通过重用,避免大量的内存开销。尤其是在iphone 单核时代。
  2. UITableView在cellForRow方法中dequeueReusableCellWithIdentifier设置重用标记。
  3. 当面屏幕中所显示的子视图都是真实存在,相互之间不重用。但是当前子视图可以重用已经init但是已经移除视图外的子视图。

实现机制

假如当前屏幕UITableView 可以最多显示6个cell,用3种不同的cell,也就是需要设置3个不同的identifier。

  1. cellForRow最多生成可以占满屏幕的cell,也就是6个。这个时候,所有的cell都不会加入到reuse cell queue。也就是生成了2组不同identifier的cell,共6个。
  2. 向上滑动,生成第7个cell。
  3. 继续滑动,第1个cell隐藏时,此cell加入reuse cell queue。
  4. 向上滑动,生成第8个cell。
  5. 继续滑动,第2个cell隐藏时,此cell加入reuse cell queue。
  6. 向上滑动,生成第9个cell。
  7. 继续滑动,第3个cell隐藏时,此cell加入reuse cell queue。
  8. 向上滑动,生成第10个cell。
  9. 此时dequeueReusableCellWithIdentifier可以从reuse cell queue获取到reuse cell,就不在创建新的cell,直接返回,重新配置数据即可,并把此cell从队列去移除。
  10. 到第12个cell,都是此逻辑。然后每3个cell以此往复。

XZPageViewController 类似搜狐新闻切换效果

先上效果图

Mou icon

github地址

https://github.com/kingundertree/XZPageViewController

说明

见过一些类似的设计,但是很多都是采用UIScrollView,add viewController,然后自己监控UIScrollView的变化值实现导航和viewController的通讯,甚至有采用UITableView横过来的方式实现,深不以为然。一方面是实现成本大,操作麻烦,再就是viewController的生命周期需要单独控制等。

更推崇系统提供的UIPageViewController方法,这个方法本来是方便实现类似读书软件的翻页效果。

功能

  1. 支持左右滑动快速切换viewController
  2. 支持viewController和导航的相互控制
  3. 支持viewController的切换效果和循环滚动

实现机制

  1. 基于UIPageViewController以及其UIPageViewControllerDataSource,UIPageViewControllerDelegate
  2. 通过UIPageViewControllerDataSource 为 UIPageViewController 添加 viewControllerBeforeViewController 或 viewControllerAfterViewController ,实现视图的切换
  3. 通过UIPageViewControllerDelegate,通知实现导航效果切换
  4. 通过setViewControllers,实现点击导航切换viewcontrollers

使用方法

目前,所有功能都已经集成到XZPageViewController中,只继承XZPageViewController,然后实现XZPageViewControllerDataSource,XZPageViewControllerDelegate。

XZPageViewControllerDataSource

1.设置导航数量

- (float)numOfPages;

2.设置导航宽度

- (float)witdhOfNav;

3.导航标题

- (NSString *)titleOfNavAtIndex:(NSInteger)index;

4.设置viewController

- (UIViewController *)viewPageController:(XZPageViewController *)pageViewController contentViewControllerForNavAtIndex:(NSInteger)index;

5.是否循环

- (BOOL)canPageViewControllerRecycle;

6.导航切换,viewcontroller是否动画展示

- (BOOL)canPageViewControllerAnimation;
XZPageViewControllerDelegate

1.viewController切换成功事件

-(UIViewController *)viewPageController:(XZPageViewController *)pageViewController pageViewControllerChangedAtIndex:(NSInteger)index;