4

I have a custom NSTextView implementation that automatically adjusts the font size so that the text fills the entire view.

I overwrote didChangeText to call my font size adjustment method. Works great when the user is editing text, but didChangeText (and the delegate method textDidChange:) are not called when the text view contents are set via bindings.

The font adjustment code needs to run whenever the text is set/changes, not only when it's changed by the user.

How can I detect all changes to the text in an NSTextView, even via bindings?

Note: If there's a better way to have the text fill the entire text view other than increasing the font size, let me know.

Mark
  • 6,647
  • 1
  • 45
  • 88
  • Did you add ? And connect the delegate property of the NSTextView (not NSScrollView) with the object which should receive the delegate. -(void)textDidChange:(NSNotification *)notification { NSLog(@"textDidChange called"); } – Anoop Vaidya Dec 14 '12 at 10:19
  • Yes, I tried using the delegate, but textDidChange: is not called when the view is updated via bindings. – Mark Dec 14 '12 at 10:49

2 Answers2

0

It would be better to set the font attributes into the NSAttributedString that is bound to the text view's "attributedString". In the textDidChange: delegate method, you can just recreate the NSAttributedString with the correct font attributes.

user1885297
  • 586
  • 2
  • 6
  • I'm doing something similar. My problem is that my font adjustment code is not called when the text view's contents are set initially. – Mark Dec 14 '12 at 16:50
  • If you are doing it right, the bound property (ie. its accessor) will return the NSAttributedString with the right font (that you have determined) attribute at all times. – user1885297 Dec 14 '12 at 17:09
  • The bound property is a simple NSString, not NSAttributedString. Nonetheless, I'd like to set a custom font. – Mark Jan 15 '13 at 17:15
  • This isn't really a correct answer to the main question. – Giles Feb 07 '19 at 11:37
0

The NSTextView method didChangeText is not called when a binding updates the text (as opposed to the text view updating the model).

didChangeText is the source of the binding update. If you override it and don't call super, the binding is broken. didChangeText calls the delegate method textDidChange.

Unfortunately, didChangeText is also called rather late in the NSTextView update process - after the layout and storage delegate calls.

I found that the NSTextStorageDelegate method "didProcessEditing" was the best way to catch changes to the bound string. Although you have to be careful what changes you can make back to the textview at this point - some calls crashed.

I answered my own similar question more fully here: NSTextView textDidChange not called through binding

Giles
  • 1,428
  • 11
  • 21
  • Thanks for the heads-up! I don't quite recall how I solved the problem back then, but these days I use a custom `NSTextStorage` to hook into `didProcessEditing`, similar to what you suggested. – Mark Feb 11 '19 at 13:37