【问题标题】:Swift: Call Function when NSTextField is EditedSwift:编辑 NSTextField 时调用函数
【发布时间】:2017-01-08 13:50:23
【问题描述】:

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

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

谢谢!

【问题讨论】:

    标签: swift macos nstextfield


    【解决方案1】:

    您将不得不使用 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
            }
        }
    }
    

    【讨论】:

    • 非常感谢。我已经在快速参考中找到了剪断的func controlTextDidChange(_ notification: Notification),但我永远不会找到使用extension 类的完整解决方案。有点复杂。还是谢谢。
    • controlTextDidChange 在您输入时为您提供实时更新; controlTextDidEndEditing 仅在您按回车键或移动到其他控件时触发。
    【解决方案2】:
    • 我发现 Swift 4 问题与
    • textfield.delegate = self
    • 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()
            //---------------------------------------------------------
        }
    }
    

    【讨论】:

    • 我得到错误 override func controlTextDidChange(_ notification: Notification) 方法没有覆盖其超类中的任何方法
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多