iOS 文字贴纸缩放实践方案
期望能探索出一套比较优的解决方案实现和剪映差不多的贴纸绘制方案,能够实现无损缩放,并且缩放时不卡顿,似乎内存占用也不是很高(不确定)。
Native 实现文字贴纸的基本原理:用户输入 、排版&创建图片、渲染到视频上。如何接受用户输入以及渲染图片到视频上不属于这篇文章讨论的范畴,本文主要介绍的中心在如何将文字绘制成一张张位图
排版&创建图片
iOS 实现排版方式有很多,虽然最底层原理都是 CoreText,但是根据场景不同具体的实践方案,因为不同Framework
封装度不同,具体的使用也会有所不同。
方案 | 优点 | 缺点 |
---|---|---|
UIKit:UITextView、UILabel、NSString(NSAttributedString……) | 封装比较好,实现代码少 | 需要在主线程访问,无法灵活调整文字排版 |
QuartzCore:CATextLayer | 封装比较好,实现代码少 | 无法获取文字排版结果、调整排版不灵活 |
TextKit:NSLayoutManager…… | 封装度一般,代码略多,能结合 UITextView 一起使用 | 学习成本比较大 |
CoreText:CTFramesetter…… | 需要自行封装,代码量最多 | 学习成本比较大 |
TextKit 的线程安全
Instances of the
NSTextContainer
,NSLayoutManager
, andNSTextStorage
classes can be accessed from threads other than the main thread as long as the app guarantees access from only one thread at a time.
这句话并不是说可以这些属性是线程安全的——必须保证每次访问都在同一个线程。
但是如果在主线程修改 NSTextStorage 中的 attributes,同时在另外一个线程尝试调用 NSLayoutManager
进行绘制其实是会有线程安全问题的。
textView.scrollEnabled 会导致内存问题
UITextView 高度很高并且设置 scrollEnabled 会有内存问题
UITextView scrollEnabled will cause memory issue
1 | UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, 200, 20000) textContainer:nil]; |
B站拖拽预览实现原理
服务端抽帧,然后把所有帧拼成一张大图