前言

一年前因为 UITableView 无法满意要求,我实现了仿佛 UITableView
的组件, DLTableView

为此实现一个自定义的 UITableView,是因为自己需要一个能无限循环滚动的
TableView。

日常的做法是安装 dataSource 的 numberOfRowsInSection:
方法重返尽量多的行数,然后在对 row
取余以落实看起来是不过循环滚动的特效。UIDatePicker 就是这样子实现的。

这种方案有个问题,假设用户间接往下滚动,仍是可以够滚动到底的,所以行数要设置的玩命大。另一方面太大的行数会招致内存使用暴涨。
UIDatePicker 的做法是安装一个靠边的行数,在用户为止滚动的时候去校正
contentOffset,由于并未动画效果,用户无法感知,在内存和意义之间赢得了平衡。可是接连往下滚的话,你会意识仍可以滚到底部,等你再一次进入的时候才会重置一下
contentOffset。所以那些方案并不到家。

因为不少缘由最后自己控制实现一个 UITableView。好处有多少个:

  1. 从执行中思索苹果是哪些实现的,有如何难题,它的 UITabeleView
    有哪些可以改进之处。这多少个不是单纯的看几篇博客或者直接看源码就足以拿走的
  2. 贯彻一个基本的 TableView 之后,可以增长诸多原生 TableView
    不富有的功效,比如说循环滚动特性。项目举办可以更进一步灵活
  3. 可以遵照新的自定义的 TableView 实现一个比官方
    UIPickerView/UIDatePicker 更好的 DLPickerView

此处先预告一下,下一篇我会讲解怎么着按照 DLTableView2018正版葡京赌侠诗, 实现
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。Tmall的
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

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图