A lightweight, high-performance rich-text library for all Apple platforms β UIKit, AppKit, and SwiftUI (including watchOS).
Note: This fork is reimplemented in Swift 6.0 with strict concurrency. While API compatibility with the original has been maintained, 100% compatibility is not guaranteed.
- β‘οΈ High performance text layout and rendering via CoreText
- π Native view embedding via attachments
- π Clickable links support
- βοΈ Text selection with copy/paste
- π¨ Custom per-line drawing callbacks
- π Auto layout integration (experimental)
- π₯οΈ SwiftUI support on all platforms, including watchOS
| Platform | Minimum Version | LTXLabel (UIKit/AppKit) | LitextLabel (SwiftUI) |
|---|---|---|---|
| iOS | 13.0+ | β | β |
| macOS | 12.0+ | β | β |
| tvOS | 13.0+ | β | β |
| visionOS | 1.0+ | β | β |
| Mac Catalyst | 13.0+ | β | β |
| watchOS | 8.0+ | β | β |
Add Litext as a dependency in your Package.swift file:
dependencies: [
.package(url: "https://github.com/Helixform/Litext.git", branch: "main")
]Or in Xcode: File β Add Package Dependencies and enter the repository URL.
import Litext
let label = LTXLabel()
view.addSubview(label)
let attributedString = NSMutableAttributedString(
string: "Hello, Litext!",
attributes: [
.font: PlatformFont.systemFont(ofSize: 16),
.foregroundColor: PlatformColor.label
]
)
label.attributedText = attributedStringLitextLabel works on all platforms, including watchOS:
import Litext
import SwiftUI
struct ContentView: View {
var body: some View {
LitextLabel("Hello, Litext!")
.selectable()
.onTapLink { url in
UIApplication.shared.open(url)
}
}
}You can also initialise with an NSAttributedString or AttributedString:
LitextLabel(attributedString: myNSAttributedString)
LitextLabel(attributedString: myAttributedString) // AttributedString (iOS 15+, macOS 12+)let mutable = NSMutableAttributedString(string: "Visit GitHub")
mutable.addAttribute(.link, value: URL(string: "https://github.com")!, range: NSRange(location: 6, length: 6))
label.attributedText = mutable
// UIKit/AppKit β implement LTXLabelDelegate
label.delegate = self
func ltxLabelDidTapOnHighlightContent(
_ ltxLabel: LTXLabel,
region: LTXHighlightRegion?,
location: CGPoint
) {
if let url = region?.attributes[.link] as? URL {
UIApplication.shared.open(url)
}
}
// SwiftUI β use the modifier
LitextLabel(attributedString: mutable)
.onTapLink { url in
UIApplication.shared.open(url)
}// Enable selection
label.isSelectable = true
label.selectionBackgroundColor = UIColor.systemBlue.withAlphaComponent(0.2)
// Access selected text
let text = label.selectedPlainText()
let attributed = label.selectedAttributedText()
// Programmatic selection
label.selectionRange = NSRange(location: 0, length: 5)
label.selectAllText()
label.clearSelection()
// SwiftUI
LitextLabel("Some selectable text")
.selectable()Use LTXAttachment to embed any view inline in the text:
// UIKit / AppKit
let attachment = LTXAttachment()
attachment.view = myCustomView // UIView or NSView
attachment.size = myCustomView.intrinsicContentSize
// watchOS (SwiftUI view instead)
let attachment = LTXAttachment()
attachment.swiftUIView = AnyView(MyCustomView())
attachment.size = CGSize(width: 100, height: 50)
// Insert attachment into attributed string
let attachmentString = NSAttributedString(
string: LTXReplacementText,
attributes: [
.ltxAttachment: attachment,
kCTRunDelegateAttributeName as NSAttributedString.Key: attachment.runDelegate
]
)let drawingAction = LTXLineDrawingAction { context, line, origin in
// Custom drawing for each line
context.setStrokeColor(UIColor.red.cgColor)
context.move(to: CGPoint(x: origin.x, y: origin.y - 2))
context.addLine(to: CGPoint(x: origin.x + 100, y: origin.y - 2))
context.strokePath()
}
attributedString.addAttribute(
.ltxLineDrawingCallback,
value: drawingAction,
range: fullRange
)On watchOS, LTXLabel (the UIView/NSView subclass) is not available. Use LitextLabel instead β it renders via an off-screen CGContext and displays the result as a SwiftUI Image.
import Litext
import SwiftUI
struct WatchContentView: View {
var body: some View {
LitextLabel(attributedString: styledText)
}
var styledText: NSAttributedString {
let s = NSMutableAttributedString(string: "Hello from Watch!")
s.addAttribute(.font, value: UIFont.boldSystemFont(ofSize: 14), range: NSRange(location: 0, length: 17))
return s
}
}For inline attachments on watchOS, provide a SwiftUI view via swiftUIView instead of view.
This project is licensed under the MIT License β see the LICENSE file for details.

