Reputation: 1506
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
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