从VVeboTableViewDemo到YYAsyncLayer(一)
知道 VVeboTableViewDemo 其实很久了,一直想研究一下,最近终于有时间了,将 VVeboTableViewDemo 用Swift做了一遍( VVeboTableViewDemo.swift ),花了两个周对iOS优化的一系列文章通读了至少一遍,发现它们对优化的点总结的很散,而且大多不适合我这样的小菜。
列如这样的问题:
首先看一下VVeboTableViewDemo的结构(由于我已经把它翻译成了Swift,我下面是用Swift版分析的,和原版的逻辑是一致的。)
其中 DataPrenstenter 是我从 VVeboTableView 中抽离出来的,他其实就是读取数据的,你不用关心。
以上这张图是 VVeboLabel 中所有的内容,高亮的那个方法是 VVeboLabel 的核心所在。
这里属于 Core Text 技术,主要是对文本的特殊处理,采用了逐行绘制
其余方法主要是对文本高亮和清除内容处理,不是重点,可以不关心。
在 VVeboTableViewCell 中,高亮的方法为核心部分。其实同 VVeboLabel 的思想是一模一样的,就是将内容异步绘制在一张图上,然后显示出来,到达减少混合,以减小GPU压力。就不贴出源码,下面会放出Demo。
这是一个设计很巧妙的类,在开始研究这个类的思路之前,我建议你看看这篇 文章 。当然如果你对 UIScrollView 足够熟悉,并且熟悉这个方法 func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) ,那么对 VVeboTableView 的思路可以一目了然了。
该方法从 iOS 5 引入,在 didEndDragging 前被调用,当 willEndDragging 方法中 velocity 为 CGPoin.zero (结束拖动时两个方向都没有速度)时, didEndDragging 中的 decelerate 为 false,即没有减速过程, willBeginDecelerating 和 didEndDecelerating 也就不会被调用。反之,当 velocity 不为 CGPoin.zero 时,scroll view 会以 velocity 为初速度,减速直到 targetContentOffset 。值得注意的是,这里的 targetContentOffset 是个指针,没错,你可以改变减速运动的目的地,这在一些效果的实现时十分有用。
以上文字 来源
微信读书的那种横滑居中效果,除了重写 UICollectionViewFlowLayout ,
也通过控制 targetContentOffset 就可以实现
图中高亮方法为核心部分
cell绘制判断逻辑
以上 VVeboTableViewDemo 源码已经全部解析完成了,那么你在惊叹作者巧妙思路的同时,肯定也很想知道这种技术的来源,和改进过程。(以下为个人猜想)
通过本文,我觉得应该了解 Core Text 、 Core Graphics 、 Hit-Test View 、 异步绘制 这几项内容,你可以通过以下推荐的文章来掌握前三种技术, 异步绘制 在下一节 YYAsyncLayer 源码分析中,我相信你不知不觉就掌握了这项技术。
最初来源
这种技术的出现是为了减轻GPU的压力,因为图层的混合是GPU做的,而在这是CPU几乎是没事可做的,所以吧GPU的混合移到CPU的 func draw(_ rect: CGRect) 去完成需求。
此技术的demo fastscrolling
技术淘汰原因
由于 retina 屏幕的出现,原来单位面积的像素增加,而CPU做的事情也变得多了起来,导致效率反而不及 subViews 方法。
AsyncDisplayKit YYKit 等新技术出现
我觉得 VVeboTableViewDemo 的出现应该也是遵循以上过程的
Core Text:
Swift之CoreText排版神器
官方文档
Core Graphics:
iOS绘图教程
Swift之你应该懂点Core Graphics
官方Demo
官方Demo Swift版本
Building Concurrent User Interfaces on iOS
响应链
iOS事件响应链中Hit-Test View的应用
iOS 事件处理 | Hit-Testing
异步绘制
/ios-concurrency/