ControlTextDidChange不适用于设置NSTextField的字符串 [英] ControlTextDidChange not working for setting string of NSTextField

查看:1224
本文介绍了ControlTextDidChange不适用于设置NSTextField的字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图找到一个方法来监视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);
}

@end

XIB显示按钮和文本字段:

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的字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆