Swift: 编辑NSTextField时调用函数

Swift: Call Function when NSTextField is Edited

我尝试使用 NSTextField 的不断变化的用户输入来动态更新另一个视图的文本。以下方法不起作用,因为它适用于 iOSosx NSTextField 有类似的东西吗?

self.equationTextField.addTarget(self, action: #selector(ViewController.textFieldDidChange(_:)), for: UIControlEvents.editingChanged)
//build error: "Use of unresolved identifier 'UIControlEvents'"

谢谢!

您将不得不使用 NSControlTextEditingDelegate。如果您使用故事板,请将 NSTextField delegate 连接到您的 ViewController。如果您以编程方式创建它,只需在代码中设置它,如下所示:textfield.delegate = self in viewDidLoad()

NSControlTextEditingDelegate 中有一个 controlTextDidChange 可以用来在编辑文本时收到通知。

extension ViewController: NSControlTextEditingDelegate {
    override func controlTextDidChange(_ notification: Notification) {
        if let textField = notification.object as? NSTextField {
            print(textField.stringValue)
            //do what you need here
        }
    }
}
  • 我发现 Swift 4 个
  • 问题
  • textfield.delegate = 自己
  • NSControlTextEditingDelegate

  • controlTextDidChange 和 controlTextDidEndEditing 在 NSControlTextEditingDelegate

  • 这是父协议 NSTextFieldDelegate 协议 NSTextFieldDelegate : NSControlTextEditingDelegate
  • 所以 VC 应该实现 NSTextFieldDelegate 而不是 NSControlTextEditingDelegate

class  MyViewController:.... NSControlTextEditingDelegate 
textfield.delegate = self
//compile error: Cannot assign value of type 'MyViewController' to type 'NSTextFieldDelegate?'

//
class  MyViewController:.... NSTextFieldDelegate 
textfield.delegate = self  //compiles ok

完整示例

//
//  MyViewController.swift
//

import Cocoa

class MyViewController: NSViewController, NSTextFieldDelegate {

    //--------------------------------------------------------------
    // MARK: -   //call in viewDidLoad
    // MARK: -
    //--------------------------------------------------------------
    func connectTONSControlTextEditingDelegate(){

        //controlTextDidChange and controlTextDidEndEditing are in NSControlTextEditingDelegate
        //this is a parent protocol of NSTextFieldDelegate
        //protocol NSTextFieldDelegate : NSControlTextEditingDelegate
        //so  implement NSTextFieldDelegate 
        //class MyViewController:.... NSTextFieldDelegate
        //then connect it here to NSTextFields

        //then override controlTextDidChange OR controlTextDidEndEditing

        self.textField0.delegate = self
        self.textField1.delegate = self

    }


    //--------------------------------------------------------------
    // MARK: -  NSControlTextEditingDelegate
    // MARK: -
    //--------------------------------------------------------------
    //called everytime you type in field
    override func controlTextDidChange(_ notification: Notification) {

        if let textField = notification.object as? NSTextField {
            if textField === textField0{
                logger.info("[controlTextDidChange][textField0]:'\(textField.stringValue)'")

            }
            else if textField === textField1{
                logger.info("[controlTextDidChange][textField1]:'\(textField.stringValue)'")

            }
            else{
                logger.error("[controlTextDidChange][UNHANDLED NSTextField]")
            }
        }
    }

    //User tapped in NSTextfields and then clicked out - text may not have changed
    //this is actually on NSObject in appkit
    //dont need both controlTextDidChange and controlTextDidEndEditing but no harm if you do
    override func controlTextDidEndEditing(_ notification: Notification){
        if let textField = notification.object as? NSTextField {

            if textField === textField0{
                logger.info("[controlTextDidEndEditing][textField0]:'\(textField.stringValue)'")

            }
            else if textField === textField1{
                logger.info("[controlTextDidEndEditing][textField1]:'\(textField.stringValue)'")

            }
            else{
                logger.error("[controlTextDidEndEditing][UNHANDLED NSTextField]")
            }
        }
    }



    //--------------------------------------------------------------
    // MARK: - NSTextFields
    // MARK: -
    //--------------------------------------------------------------
    @IBOutlet weak var textField0: NSTextField!
    @IBOutlet weak var textField1: NSTextField!

    //--------------------------------------------------------------
    // MARK: - viewDidLoad
    // MARK: -
    //--------------------------------------------------------------
    override func viewDidLoad() {
        super.viewDidLoad()

        //---------------------------------------------------------
        //setup text change delegates - see extension above
        connectTONSControlTextEditingDelegate()
        //---------------------------------------------------------
    }
}