NSTextField的文本更改通知

ale*_*ail 51 cocoa nsnotifications nstextfield observer-pattern

我想使用这个问题答案中的代码: 如何在NSTextField观察NSTextField的值,以便观察存储在NSTextField中的字符串的变化.

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

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

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

NSG*_*God 104

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

只需将nib文件中的delegate插座连接NSTextField到控制器类,并实现如下所示:

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

如果您正在创建的NSTextField程序,你可以使用NSTextFieldsetDelegate:方法创建后指定的代表:

NSTextField *textField = [[[NSTextField alloc] initWithFrame:someRect] autorelease];
[textField setDelegate:self]; // or whatever object you want
Run Code Online (Sandbox Code Playgroud)

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

可可基础指南:代表和数据来源

关于什么id <NSTextFieldDelegate>意思:它意味着一个通用对象(id)声明自己符合<NSTextFieldDelegate>协议.有关协议的更多信息,请参阅Objective-C编程语言:协议.

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


Dar*_*der 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")
    }
}
Run Code Online (Sandbox Code Playgroud)

}

控制台输出:

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

Changed text = asdasdasddsada
Run Code Online (Sandbox Code Playgroud)


onm*_*133 6

您应该使用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)
  }
}
Run Code Online (Sandbox Code Playgroud)