Home

Awesome

<p align="center"> <img src="/images/banner.png" /> </p>

StyledTextKit is a declarative attributed string library for fast rendering and easy string building. It serves as a simple replacement to NSAttributedString and UILabel for background-thread sizing and bitmap caching.

Features

Installation

Just add StyledTextKit to your Podfile and install. Done!

pod 'StyledTextKit'

Usage

Building NSAttributedStrings

StyledTextKit lets you build complex NSAttributedStrings:

let attributedString = StyledTextBuilder(text: "Foo ")
  .save()
  .add(text: "bar", traits: [.traitBold])
  .restore()
  .add(text: " baz!")
  .build()
  .render(contentSizeCategory: .large)

Foo bar baz!

The basic steps are:

Rendering Text Bitmaps

Create a StyledTextRenderer for sizing and rendering text by initializing it with a StyledTextString and a UIContentSizeCategory.

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

Once created, you can easily get the size of the text constrained to a width:

let size = renderer.size(in: 320)

You can also get a bitmap of the text:

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

StyledTextView

To make rendering and layout of text in a UIView simpler, use StyledTextView to manage display as well as interactions. All you need is a StyledTextRenderer and a width and you're set!

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

Set a delegate on the view to handle tap and long presses:

view.delegate = self

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

Background Rendering

StyledTextKit exists to do background sizing and rendering of text content so that scrolling large amounts of text is buttery smooth. The typical pipeline to do this is:

  1. Get the current width and UIContentSizeCategory
  2. Go to a background queue
  3. Build text
  4. Warm caches
  5. Return to the main queue
  6. Configure your views
// 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)
  }
}

FAQ

Why not use UITextView?

Prior to iOS 7, UITextView just used WebKit under the hood and was terribly slow. Now that it uses TextKit, it's significantly faster but still requires all sizing and rendering be done on the main thread.

For apps with lots of text embedded in UITableViewCells or UICollectionViewCells, UITextView bring scrolling to a grinding halt.

Acknowledgements