web-dev-qa-db-ja.com

NSTextFieldのテキスト変更通知

この質問に対する答えからのコードを使用したいと思います: NSTextFieldに保存された文字列の変更を観察するために、NSTextFieldでNSTextField の値を観察する方法。

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

ここで使用されるクラスはNSTextViewです。 NSTextViewDidChangeSelectionNotificationの代わりに使用するNSTextFieldで通知を見つけることができません。

この場合に使用できるNSTextFieldで利用可能な通知はありますか?

49
alecail

テキストフィールドの値がいつ変更されたかを検出する場合は、NSTextFieldNSControlから継承する controlTextDidChange: デリゲートメソッドを使用できます。

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全体で使用される基本的なデザインパターンの1つです。簡単に言えば、オブジェクトをサブクラス化してその追加の動作を追加する複雑さに煩わされることなく、標準オブジェクト(この場合はユーザーインターフェイスオブジェクト)の動作を簡単にカスタマイズできます。たとえば、テキストフィールドのテキストが変更されたことを検出する別の低レベルの方法は、独自のカスタムNSTextFieldサブクラスを作成し、そのサブクラスで keyDown: メソッドNSTextFieldNSResponderから継承します。ただし、そのようなサブクラス化は、オブジェクトの継承階層に関する詳細な知識を必要とする可能性があるため、困難です。詳細については、間違いなく以下をチェックしてください。

ココアの基礎ガイド:デリゲートとデータソース

id <NSTextFieldDelegate>の意味については、<NSTextFieldDelegate>プロトコルに準拠していると宣言する汎用オブジェクト(id)を意味します。プロトコルの詳細については、 Objective-Cプログラミング言語:プロトコル を参照してください。

サンプルGitHubプロジェクト: https://github.com/NSGod/MDControlTextDidChange

103
NSGod

Xcode 9.2。 with 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
7
Darkwonder

In Swiftそれは

public override func controlTextDidChange(_ obj: Notification) {


}
0
Mark Bridges

フィールドエディター を読んでほしいと思います。これは、本質的に(隠された)NSTextViewであり、特定のウィンドウ内のすべてのNSTextFieldsへのテキスト入力を処理します。 "フィールドエディターでの委任と通知の使用" のセクションは、正しい方向を示しているはずです。

0
Sean

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)
  }
}
0
onmyway133