心想事成 UITableView 以及思维

前言

一年前因为 UITableView 不可以满意要求,我实现了看似 UITableView
的组件, DLTableView

为此实现一个自定义的 UITableView,是因为我急需一个能最好循环滚动的
TableView。

平常的做法是设置 dataSource 的 numberOfRowsInSection:
方法再次来到尽量多的行数,然后在对 row
取余以贯彻看起来是最好循环滚动的特效。UIDatePicker 就是这样子实现的。

这种方案有个问题,假设用户一向往下滚动,还是可以够滚动到底的,所以行数要安装的尽心大。另一方面太大的行数会招致内存使用暴涨。
UIDatePicker 的做法是安装一个合理的行数,在用户截至滚动的时候去校正
contentOffset,由于尚未动画效果,用户无法感知,在内存和效益之间赢得了平衡。不过接连往下滚的话,你会发现仍是可以够滚到底部,等您重新进入的时候才会重置一下
contentOffset。所以那么些方案并不健全。

因为众多缘故最后自己说了算实现一个 UITableView。好处有多少个:

  1. 从履行中考虑苹果是怎么样促成的,有什么样困难,它的 UITabeleView
    有什么可以革新之处。这么些不是一味的看几篇博客或者直接看源码就可以取得的
  2. 兑现一个为主的 TableView 之后,可以添加诸多原生 TableView
    不负有的职能,比如说循环滚动特性。项目推行可以进一步灵活
  3. 能够遵照新的自定义的 TableView 实现一个比官方
    UIPickerView/UIDatePicker 更好的 DLPickerView

此处先预告一下,下一篇我会讲解如何依照 DLTableView 实现
DLPickerView。那些 pickerView 有刹那间特色:

  1. 类似 UITableView 的 delegate 和 dataSource,同时可以自定义
    cell,用法完全类似 UITableView,灵活性更高。
  2. 可以设置连续的可选区域,用户不可能滚动到可选区域之外
  3. 可以安排循环滚动或者不循环滚动
  4. DLPickerViewDelegate 提供对各种 cell 基于近来职务的视图自定义

DLTableView
的 GitHub 地址是
https://github.com/danleechina/DLTableView

上边最先讲哪些实现一个自定义的 TableView。

关键点

自定义 TableView 的实现有四个关键点:

  1. Cell 复用
  2. 找到实现的切入点

Cell 复用比较好通晓,因为内存是零星的,不可以无限多的生成 Cell 实例。

Cell 复用的兑现也相比较简单,给每种 Cell 类设置一个
identifier,以此为键,值为一个涵盖该 Cell 类的 set 集合。Cell
滚出可视域时候加到 set 里面,Cell 出现在可视域时从 set
里面获取一个,假使 set 里面没有的话则生成一个。

那么切入点呢?

第一,大家的自定义 DLTableView 是基于 UIScrollView
的,UIScrollView
提供了很好的轮转效应,即使在应用的时候发现依旧有点不太如意的地点,比如以动画的法门设置
contentOffset
时迫于做到设置一个成就动画的回调,还有就是比如说对滚动的绊脚石做调整。

今昔请想想一个问题,在怎么时间给 DLTableView 添加一个 Cell,也就是说将
Cell 作为 TableView 的子视图或者后人视图?以及当 Cell
从用户视线中流失时将 Cell 从 DLTableView
中移除,并加入到复用的行列中?

率先想到的是 scrollViewDidScroll:,在 UIScrollView 滚动的时候添加
Cell。不过 scrollViewDidScroll 是代理实现的,作为后续自 UIScrollView
DLTableView 本身不应当实现这多少个代理。而且在 contentSize 未知的时候
UIScrollView 可能一直不可能滚动。

理所当然大家可以 hook 掉 UIScrollViewsetDelegate: 方法,然后在自定义
TableView 里面实现所有 UIScrollViewDelegate
的法子,在这么些主意里面再回调给接纳自定义 TableView 的 delegate。淘宝的
LazyScrollView
就是这样实现的 (但是它只复写了 scrollViewDidScroll:
方法,其他办法是因此动态转发来兑现的)。这种方案的先天不足是要手动设置
contentSize

本人这边的贯彻是行使 layoutSubviews。每一次起初化的时候,UIView
都会调用该办法,在这多少个艺术里面我们可以起先化最初的可见 Cell,以及
contentSize。灵感来源于与苹果的合法
demo:StreetScroller

另外,当 UIScrollView
滚动的时候,会反复的调用该方法。这样我们就足以动态的将 Cell 参预或去掉。

这边补充某些,有时候 scrollViewDidScroll:
的调用频率没大家想的那么多的时候,你也可以实现
layoutSubviewslayoutSubviews 的效率比 scrollViewDidScroll:
高,当然绝不遗忘调用 [super layoutSubviews]

心想事成细节

  1. TableView 可能会有 header 或者 footer,所以在盘算中度的时候每个 cell
    的岗位要抬高 header 中度的舞狮,统计 contentSize
    的冲天的时候要增长 footer 的万丈。
  2. TableView 可以不惟有 row 还足以更加区分每个
    section,关键一点是各类 section 也得以有 header 和 footer,所以测算
    cell 的职务的时候会有那么一些不直观,同时 section 的 header 和
    footer 在 TableView 中的地方是滚动的,到顶的时候又是悬浮在 row
    下面,那一点要注意。
  3. UITableView 扶助将某个 Cell 滚动到顶部,自定义的时候可以设想将 Cell
    滚到顶、中、底。
  4. 点击。一般不会在各样 Cell 里面加一个 tap gesture
    recognizer。我的做法是在 TableView 层面加一个 Tap gesture
    recognizer,这样每一回识别到点击的时候,可以具体分配到某个
    cell。当然还有设置点击效果(比如 cell 点击变灰)。

DLTableView

我这边贯彻了一个自定义 TabelView,DLTableView

目前 DLTableView 实现的特点有:

  1. 类似 UITableViewDataSource
    DLTableViewDataSource,使用者可以实现 dataSource
    来自定义行数和每一行的 cell
  2. 类似 UITableViewDelegate
    DLTableViewDelegate,目前带有点击逻辑、自定义中度和某个 Cell
    滚出可视区域时候的回调
  3. 可以循环滚动,同时内存使用不会并发暴涨(比如 UITableView
    就会暴涨)
  4. 点击某一行可以滚动到顶、中、底

你可以将 DLTableView 看做是一个简化版的 UITableView,它没有
section,唯有 row,也从不实现每个行的分割线,更未曾兑现 UITableView
里面的左滑 cell 自定义菜单这么些效应,而且如今还不匡助活动测算行高。

但是出于 DLTableView
的实现是开源可见的,所以您可以依照此做更加的自定义。

更好的 TableView

地点说了那么多,都是在讲怎么兑现一个类似 UITableView
TableView,重假诺寨子。

那么怎么样依照山寨版的 TableView,提供一个更好的 TableView ?

第一什么叫做更好的 TableView ?我收拾了如下:

  1. 机关总结以及缓存 Cell 中度,市面上有许多息息相关开源代码,你可以查看。
  2. 异步构建视图,以及加载数据,参考 AsyncDisplay基特(Kit)(Texture) 的思想。

引用

  1. StreetScroller
  2. iOS 异构滚动视图 LazyScrollView
    一些兑现细节的尖锐解读
  3. LazyScrollView

相关文章