nathan
nathan

Reputation: 1506

NSTextStorage subclass in Swift doesn't update UITextView

I'm trying to create a simple NSTextStorage subclass in Swift, but when I type into my textView, no text appears.

Here's my setup code in my view controller

var textView: UITextView!

var textStorage: CustomTextStorage?

override func viewDidLoad() {
    super.viewDidLoad()

    textStorage = CustomTextStorage()

    let layoutManager = NSLayoutManager()
    textStorage!.addLayoutManager(layoutManager)

    let textContainer = NSTextContainer(size: view.bounds.size)
    layoutManager.addTextContainer(textContainer)

    textView = UITextView(frame: view.bounds, textContainer: textContainer)
    view.addSubview(textView)
}

And in my CustomTextStorage subclass:

var store: NSMutableAttributedString = NSMutableAttributedString()

func string() -> NSString {
    return store.string
}

override func attributesAtIndex(location: Int, effectiveRange range: NSRangePointer) -> [NSObject : AnyObject] {
    return store.attributesAtIndex(location, effectiveRange: range)
}

override func replaceCharactersInRange(range: NSRange, withString str: String) {
    store.replaceCharactersInRange(range, withString: string)
    edited(NSTextStorageEditActions.EditedCharacters, range: range, changeInLength:countElements(str) - range.length)
}

override func setAttributes(attrs: [NSObject : AnyObject]?, range: NSRange) {
    store.setAttributes(attrs, range: range)
    edited(NSTextStorageEditActions.EditedAttributes, range: range, changeInLength: 0)
}

Problem: Every time I type into the textView, replaceCharactersInRange:withString: gets called with the correct string, but a range of {0,0}, and nothing appears in the textView. The suggestions bar above the keyboard does change though.

As an aside, setAttributes: gets called with a range of {0,1} (the correct value), causing an exception:

NSMutableRLEArray replaceObjectsInRange:withObject:length:: Out of bounds'

I've avoided this by checking the range is in bounds first, but this doesn't fix the first issue.

Any help would be fantastic!

Upvotes: 0

Views: 985

Answers (1)

nathan
nathan

Reputation: 1506

It looks like I had this in CustomTextStorage.swift underneath what I showed:

override func processEditing() {
}

Needed to call super.processEditing() within that method. Whoops.

Leaving this here as I've seen some similar questions on other sites and mailing lists that got no answer.

Upvotes: 2

Related Questions