我试图找到一个方法来监视NSTextField的文本的变化。我尝试了 - (void)controlTextDidChange:(NSNotification *)obj 的委托方法,但它只有当用户输入到文本字段时才起作用。如果以编程方式设置文本字段字符串(例如使用按钮),则 controlTextDidChange 将不起作用。
I'm trying to find a method that monitors the text of NSTextField for changes. I tried the delegate method of -(void)controlTextDidChange:(NSNotification *)obj but it only works when the user types into the text field. If the text field string is programmatically set, such as with a button, the controlTextDidChange doesn't work.
有没有一个方法或另一种方法,我可以用来监视NSTextField的内容进行更改?
Is there a method or another approach that I can use to monitor the contents of a NSTextField for changes?
我的ButtonText类(设置为NSTextField的委托) p>
My ButtonText class (set as delegate for the NSTextField):
#import "ButtonText.h" @interface ButtonText () @property (weak) IBOutlet NSTextField *buttonField; @end @implementation ButtonText - (IBAction)buttonTextA:(id)sender { [_buttonField setStringValue:@"text A here"]; } - (IBAction)buttonTextB:(id)sender { [_buttonField setStringValue:@"and text B stuff"]; } - (void)controlTextDidChange:(NSNotification *)obj { NSLog(@"controlTextDidChange: %@", _buttonField.stringValue); } @endXIB显示按钮和文本字段:
The XIB showing the buttons and text field:
推荐答案一种方法是使用KVO。特别是,添加 ButtonText 实例作为 buttonField 的观察者 stringValue 。
One approach is to use KVO. In particular, add the ButtonText instance as an observer of buttonField's stringValue.
更详细地说,在 ButtonText @property IBOutlet buttonField 已设置(即如果 ButtonText 是 NSWindowController 子类 -windowDidLoad ,如果 ButtonText 是 NSViewController -loadView ),调用
In more detail, in your file ButtonText, once the @property IBOutlet buttonField has been set (i.e. if ButtonText is an NSWindowController subclass, in -windowDidLoad, and if ButtonText is an NSViewController subclass in -loadView), call
[self.buttonField addObserver:self forKeyPath:@"stringValue" options:0 context:&ButtonTextKVOContext];之前在文件中定义 ButtonTextKVOContext :
static int ButtonTextKVOContext = 0;然后覆盖 observeValueForKeyPath:ofObject:change:context:如下:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if (context != &ButtonTextKVOContext) { [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; return; } if (object == self.buttonField) { if ([keyPath isEqualToString:@"stringValue"]) { NSLog(@"controlTextDidChange: %@", _buttonField.stringValue); } } }编辑
由于 ButtonText 不是 NSWindowController 或 NSViewController ,我们将使用稍微不同的方法。像以前一样,我们将开始观察 @property IBOutlet buttonField 已设置。要做到这一点,综合属性 buttonField 成为成员变量 mButtonField 写
Edit
Since ButtonText is not a subclass of NSWindowController or NSViewController, we'll use a slightly different approach. As before, we'll want to start observing "once the @property IBOutlet buttonField has been set". To do this, synthesize the property buttonField to be the member variable mButtonField writing
@synthesize buttonField = mButtonField;并覆写 buttonField :
- (void)setButtonField:(NSTextField *)buttonField { [self stopObservingButtonField]; mButtonField = buttonField; [self startObservingButtonField]; }我们需要确保 ButtonText 在释放按钮字段时停止观察,因此覆盖 -dealloc 如下:
We need to make sure that ButtonText stops observing the button field when it deallocates as well, so override -dealloc as follows:
- (void)dealloc { [self stopObservingButtonField]; }它仍然是定义方法 -stopObservingButtonField 和 -startObservingButtonField :
- (void)stopObservingButtonField { if (mButtonField) { [mButtonField removeObserver:self forKeyPath:@"stringValue" context:&ButtonTextKVOContext]; } } - (void)startObservingButtonField { if (mButtonField) { [self.buttonField addObserver:self forKeyPath:@"stringValue" options:0 context:&ButtonTextKVOContext]; } }由于这种安排,方法的 mButtonField 变量。 (这不是真的,但如果我们设置 mButtonField ,我们必须确保首先停止观察其旧值的 @stringValue 键路径并开始观察它的新值的stringValue键路径。这样做而不是简单地调用 -setButtonField: )
As a result of this arrangement, we must never set the mButtonField variable outside of the -setButtonField: method. (This isn't quite true, but if we do set mButtonField we must be sure to first of all stop observing its old value's @"stringValue" key path and start observing its new value's @"stringValue" key path. Doing this rather than simply calling -setButtonField: would very likely simply constitute code repetition and not be worthwhile.)
如需参考,请参阅Apple的 NSKeyValueObserving 协议上的Cocoa / Reference / Foundation / Protocols / NSKeyValueObserving_Protocol / Reference / Reference.htmlrel =nofollow>文档。
For reference, check out Apple's documentation on the NSKeyValueObserving protocol.
更多推荐
ControlTextDidChange不适用于设置NSTextField的字符串
发布评论