NSTextField的文本更改通知

问题描述 投票:49回答:5

我想使用来自这个问题的答案的代码:在NSTextField上的How to observe the value of an NSTextField,以便观察存储在NSTextField中的字符串的变化。

[[NSNotificationCenter defaultCenter]
    addObserverForName:NSTextViewDidChangeSelectionNotification
    object:self.textView 
    queue:[NSOperationQueue mainQueue] 
    usingBlock:^(NSNotification *note){
    NSLog(@"Text: %@", self.textView.textStorage.string);
}];

这里使用的类是NSTextView。我在NSTextField中找不到通知而不是使用NSTextViewDidChangeSelectionNotification。

NSTextField中是否有可用于此情况的通知?

cocoa observer-pattern nstextfield nsnotifications
5个回答
103
投票

如果您只想检测文本字段的值何时发生更改,可以使用controlTextDidChange:NSTextField继承的NSControl委托方法。

只需将nib文件中delegateNSTextField出口连接到控制器类,并实现如下所示:

- (void)controlTextDidChange:(NSNotification *)notification {
    NSTextField *textField = [notification object];
    NSLog(@"controlTextDidChange: stringValue == %@", [textField stringValue]);
}

如果您以编程方式创建NSTextField,则可以在创建后使用NSTextFieldsetDelegate:方法来指定委托:

NSTextField *textField = [[[NSTextField alloc] initWithFrame:someRect] autorelease];
[textField setDelegate:self]; // or whatever object you want

委托是整个Cocoa中使用的基本设计模式之一。简而言之,它允许您轻松自定义标准对象(在本例中为用户界面对象)的行为,而不必涉及必须子类化对象以添加其他行为。例如,检测文本字段中的文本何时发生更改的另一种低级方法可能是创建自己的自定义NSTextField子类,在该子类中,您可以覆盖keyDown:NSTextField继承的NSResponder方法。但是,这样的子类化很难,因为它可能要求您对对象的继承层次结构有深入的了解。有关详细信息,请务必查看以下内容:

Cocoa Fundamentals Guide: Delegates and Data Sources

关于id <NSTextFieldDelegate>的含义:它表示一个通用对象(id)声明自己符合<NSTextFieldDelegate>协议。有关协议的更多信息,请参阅The Objective-C Programming Language: Protocols

示例GitHub项目位于:https://github.com/NSGod/MDControlTextDidChange


8
投票

Xcode 9.2。使用Swift 4.0.3。

必须通过接口构建器连接NSTextField才能使此实现正常工作。

import Cocoa

@objc public class MyWindowController: NSWindowController, NSTextFieldDelegate {

@IBOutlet weak var myTextField: NSTextField!

// MARK: - ViewController lifecycle -

override public func windowDidLoad() {
    super.windowDidLoad()
    myTextField.delegate = self
}

// MARK: - NSTextFieldDelegate -

public override func controlTextDidChange(_ obj: Notification) {
    // check the identifier to be sure you have the correct textfield if more are used 
    if let textField = obj.object as? NSTextField, self.myTextField.identifier == textField.identifier {
        print("\n\nMy own textField = \(self.myTextField)\nNotification textfield = \(textField)")
        print("\nChanged text = \(textField.stringValue)\n")
    }
}

}

控制台输出:

My own textField = Optional(<myApp.NSTextField 0x103f1e720>)
Notification textfield = <myApp.NSTextField: 0x103f1e720>

Changed text = asdasdasddsada

0
投票

我相信你想阅读field editor,它本质上是一个(隐藏的)NSTextView,它处理给定窗口中所有NSTextFields的文本输入。关于"Using Delegation and Notification With the Field Editor"的部分应该指出你正确的方向。


0
投票

在Swift中它是

public override func controlTextDidChange(_ obj: Notification) {


}

0
投票

你应该使用NSTextFieldDelegate并实现controlTextDidChange。在macOS 10.14和Swift 4.2中测试

import Cocoa

class ViewController: NSViewController, NSTextFieldDelegate {

  @IBOutlet weak var textField: NSTextField!

  override func viewDidLoad() {
    super.viewDidLoad()

    textField.delegate = self
  }

  func controlTextDidChange(_ obj: Notification) {
    let textField = obj.object as! NSTextField
    print(textField.stringValue)
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.