I'm pretty new to mac development (coming from a web and iOS background) and I can't work out how I could get a notification every time the value of an NSTextView changes. Any ideas?
Asked
Active
Viewed 1.3k times
4 Answers
39
Ups I just saw that you want a callback from NSTextView and not NSTextField
Just add in the header of the object which should be the delegate the protocol
@interface delegateAppDelegate : NSObject <NSApplicationDelegate, NSTextViewDelegate> {
NSWindow *window;
}
After that you add a method like
-(void)textDidChange:(NSNotification *)notification {
NSLog(@"Ok");
}
Make sure you connected the delegate property of the NSTextView (not NSScrollView) with the object which should receive the delegate
-
That's it! I'm pretty sure this was one of the things I tried, but obviously didn't quite get it right. Its working now :-) Thanks! – tarnfeld Mar 05 '11 at 11:56
-
2NSTextViewDelegate implements NSTextDelegate that's what that works but you could also use specific NSTextViewDelegate methods like - (BOOL)textView:(NSTextView *)aTextView shouldChangeTextInRange:(NSRange)affectedCharRange replacementString:(NSString *)replacementString – valexa Apr 24 '12 at 10:53
-
8This will only get changes from the user interacting with the NSTextView directly (e.g. the user types in the textview or copies and pastes into it or cuts from it). It won't catch changes to the textView if you programmatically change the textView as in `textView.string = @"Foo";`. For that you need to be the delegate of the textview's textStorage, as in `textView.textStorage.delegate = self;` and implement `- (void)textStorageWillProcessEditing:(NSNotification *)aNotification` on the class of the object that is self. This well get both user-driven changes & direct property setter changes. – Joel Jan 07 '15 at 02:07
-
Thanks Joel, was having a bad time finding this info. – Ian Bytchek Sep 14 '16 at 18:20
5
Here's the solution:
NSTextView *textView = ...;
@interface MyClass : NSObject<NSTextStorageDelegate>
@property NSTextView *textView;
@end
MyClass *myClass = [[MyClass alloc] init];
myClass.textView = textView;
textView.textStorage.delegate = myClass;
@implementation MyClass
- (void)textStorageDidProcessEditing:(NSNotification *)aNotification
{
// self.textView.string will be the current value of the NSTextView
// and this will get invoked whenever the textView's value changes,
// BOTH from user changes (like typing) or programmatic changes,
// like textView.string = @"Foo";
}
@end

Joel
- 2,285
- 2
- 21
- 22
0
set the nstextfield's delegate. in the .h file of the delegate you add the delegate protocol
In the .m file you add a method like -(void)controlTextDidChange:(NSNotification *)obj {
NSLog(@"ok");
}
I hope that helps

lbrndnr
- 3,361
- 2
- 24
- 34
-
1
-
-
3I'm afraid https://developer.apple.com/library/mac/documentation/cocoa/reference/applicationkit/classes/NSTextView_Class/Reference/Reference.html clearly shows NSTextView inherits from NSText which inherits from NSView. NSTextField inherits from NSControl which also inherits from NSView. controlTextDidChange is a delegate method of NSControl which means NSTextField has access to controlTextDidChange but NSTextView does not because it doesn't inherit from NSControl or NSTextField. – Winter Dragoness Feb 28 '14 at 17:34
-3
Set the delegate and then use
- (void) controlTextDidChange: (NSNotification *) notification
{
}

Craig
- 89
- 4