StyledTextKit 0.2.0

StyledTextKit 0.2.0

Ryan Nystrom维护。



  • Ryan Nystrom

StyledTextKit 是一个用于快速渲染和简单字符串构建的声明式属性字符串库。它作为 NSAttributedStringUILabel 的简单替代方案,用于后台线程大小和位图缓存。

功能

  • 声明式属性字符串构建 API
  • 在不产生清理器警告的情况下,在后台线程中查找文本大小
  • 缓存渲染文本位图以提高性能
  • 自定义属性交互处理(链接点击等)

安装

只需将 StyledTextKit 添加到您的 Podfile 中并安装即可。完成!

pod 'StyledTextKit'

使用

构建 NSAttributedString

StyledTextKit 允许您构建复杂的 NSAttributedString

  • 在重用字符串当前属性的同时附加 NSAttributedStringString,从而节省您反复使用 .font.foregroundColor 进行样式的重复操作。
  • 混合复杂的字体特性,如 粗体斜体,以形成 粗斜体
  • 处理字符串渲染时的动态文本大小。允许您一次性构建字符串,并在设备文本大小变化时重新渲染。
  • 调用 save()restore() 来推送/弹出样式设置,从而在不编写复杂代码的情况下构建复杂的文本样式。
let attributedString = StyledTextBuilder(text: "Foo ")
  .save()
  .add(text: "bar", traits: [.traitBold])
  .restore()
  .add(text: " baz!")
  .build()
  .render(contentSizeCategory: .large)

Foo bar baz!

基本步骤是

  • 创建一个 StyledTextBuilder
  • 添加 StyledText 对象
  • 完成时调用 build() 来生成一个 StyledTextString 对象
  • 调用 render(contentSizeCategory:) 以创建一个 NSAttributedString

渲染文本位图

通过用 StyledTextStringUIContentSizeCategory 初始化来为尺寸和渲染创建一个 StyledTextRenderer

let renderer = StyledTextRenderer(
  string: string,
  contentSizeCategory: .large
)

创建后,您可以轻松获取约束在一定宽度内文本的大小

let size = renderer.size(in: 320)

您还可以获取文本的位图

let result = renderer.render(for: 320)
view.layer.contents = result.image

StyledTextView

要简化 UIView 中的文本渲染和布局,请使用 StyledTextView 来管理显示和交互。您只需要一个 StyledTextRenderer 和一个宽度即可!

let view = StyledTextView()
view.configure(with: renderer, width: 320)

设置视图的代理以处理点击和长按

view.delegate = self

// StyledTextViewDelegate
func didTap(view: StyledTextView, attributes: [NSAttributedStringKey: Any], point: CGPoint) {
  guard let link = attributes[.link] else { return }
  show(SFSafariViewController(url: link))
}

后台渲染

StyledTextKit 存在是为了在后台对文本内容进行尺寸和渲染,以便平滑地滚动大量文本。执行此操作的典型流程是

  1. 获取当前宽度和 UIContentSizeCategory
  2. 转到后台队列
  3. 构建文本
  4. 预热缓存
  5. 返回主队列
  6. 配置您的视图
// ViewController.swift

let width = view.bounds.width
let contentSizeCategory = UIApplication.shared.preferredContentSizeCategory

DispatchQueue.global().async {
  let builder = StyledTextBuilder(...)
  let renderer = StyledTextRenderer(string: builder.build(), contentSizeCategory: contentSizeCategory)
    .warm(width: width) // warms the size cache

  DispatchQueue.main.async {
    self.textView.configure(with: renderer, width: width)
  }
}

常见问题问答

为什么不用 UITextView

在 iOS 7 之前,UITextView 在底层数据上使用 WebKit,速度极慢。现在它使用了 TextKit,速度显著提高,但仍需要在主线程上完成所有尺寸和渲染操作。

对于包含大量文本的 UITableViewCellUICollectionViewCell 的应用,UITextView 会使滚动陷入停顿。

致谢