Text change notification for an NSTextField

微笑、不失礼 提交于 2019-11-28 04:50:29

If you just want to detect when the value of a text field has changed, you can use the controlTextDidChange: delegate method that NSTextField inherits from NSControl.

Just connect the delegate outlet of the NSTextField in the nib file to your controller class, and implement something like this:

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

If you're creating the NSTextField programmatically, you can use NSTextField's setDelegate: method after creation to specify the delegate:

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

Delegation is one of the fundamental design patterns used throughout Cocoa. Briefly, it allows you to easily customize the behavior of standard objects (in this case, user interface objects) without the complexity involved in having to subclass the object to add that additional behavior. For example, another lower-level way to detect when the text in a textfield has changed might be to create your own custom NSTextField subclass in which you override the keyDown: method that NSTextField inherits from NSResponder. However, subclassing like that is difficult because it can require that you have an intimate knowledge of the object's inheritance hierarchy. For more info, definitely check out the following:

Cocoa Fundamentals Guide: Delegates and Data Sources

Regarding what id <NSTextFieldDelegate> means: it means a generic object (id) that declares itself as conforming to the <NSTextFieldDelegate> protocol. For more info on protocols, see The Objective-C Programming Language: Protocols.

Sample GitHub project at: https://github.com/NSGod/MDControlTextDidChange

Xcode 9.2. with Swift 4.0.3.

The NSTextField must be connected via interface builder for this implementation to work.

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")
    }
}

}

Console output:

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

Changed text = asdasdasddsada
Sean

I believe you want to read up on the field editor which is essentially a (hidden) NSTextView that handles the text input to all the NSTextFields in a given window. The section on "Using Delegation and Notification With the Field Editor" should point you in the right direction.

In Swift it's

public override func controlTextDidChange(_ obj: Notification) {


}

You should use NSTextFieldDelegate and implement controlTextDidChange. Test in macOS 10.14 and 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)
  }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!