- December 17, 2024
- Mins Read
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.
Just add StyledTextKit
to your Podfile and install. Done!
pod ‘StyledTextKit’
StyledTextKit
lets you build complex NSAttributedString
s:
NSAttributedString
s or String
s while re-using the string’s current attributes, saving you from repetitive .font
and .foregroundColor
styling.save()
and restore()
to push/pop style settings, letting you build complex text styles without complex code.
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:
StyledTextBuilder
StyledText
objectsbuild()
when finished to generate a StyledTextString
objectrender(contentSizeCategory:)
to create an NSAttributedString
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
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))
}
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:
UIContentSizeCategory
// 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)
}
}
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 UITableViewCell
s or UICollectionViewCell
s, UITextView
bring scrolling to a grinding halt.
A vertical stackview which takes subviews with different widths and adds them to it's rows with paddings, spacings etc.
AudioManager is a Swift package that provides a modular and easy-to-use interface for implementing audio feedback in your applications. It ...