Indenting Text with Text Kit

Episode #211 | 18 minutes | published on March 3, 2016
Subscribers Only
Sam joins us again to cover how to change text layout dynamically as you type. He will implement a feature common in Markdown editors where typing dash followed by a space indents the list. In the process you'll learn about more of the Text Kit API. If you've ever wondered what type of work goes into building a text editor, this episode is for you!

About the Author

Sam Soffes is an experienced iOS developer and regular contributor to NSScreencast, with extensive experience in TextKit. You find Sam on Twitter.

Episode Links

Implementing the Text Storage

class IndentationTextStorage: BaseTextStorage {

    static let indentationAttributeName = "IndentationTextStorage.indentationAttribute"

    override func processEditing() {
        super.processEditing()

        let text = string as NSString
        let bounds = NSRange(location: 0, length: text.length)

        let attributeName = self.dynamicType.indentationAttributeName

        // Reset
        removeAttribute(attributeName, range: bounds)

        // Loop through lines
        text.enumerateSubstringsInRange(bounds, options: .ByLines) { [weak self] substring, range, _, _ in
            guard let line = substring else { return }

            // Add custom attribute
            if line.hasPrefix("- ") {
                self?.addAttribute(attributeName, value: 1, range: range)
            }
        }

        dispatch_async(dispatch_get_main_queue()) { [weak self] in
            self?.layoutManagers.forEach { $0.invalidateLayoutForCharacterRange(bounds, actualCharacterRange: nil) }
        }
    }
}
blog comments powered by Disqus