如何实时检查 NSTextField - Swift OS X

How to live check a NSTextField - Swift OS X

我目前正在制作一个用 Swift 编写的 OS X 应用程序。我想要做的是当用户在 NSTextField 中输入文本时,我想要 运行 一个检查值并将其添加到标签的函数。我将如何在 swift 中执行此操作?

  1. 符合 ViewController 协议 NSTextDelegate
  2. ViewController 指定为 TextField 的代表。
  3. 实施controlTextDidChange方法。

    import Cocoa
    
    @NSApplicationMain
    class AppDelegate: NSObject, NSApplicationDelegate, NSTextFieldDelegate {
    
        @IBOutlet weak var window: NSWindow!
        @IBOutlet weak var textField: NSTextField!
        @IBOutlet weak var label: NSTextField!
    
    
        func applicationDidFinishLaunching(aNotification: NSNotification)
        {
            textField.delegate = self
        }
    
        override func controlTextDidChange(notification: NSNotification)
        {
            let object = notification.object as! NSTextField
            self.label.stringValue = object.stringValue
        }
    
        func applicationWillTerminate(aNotification: NSNotification) {
            // Insert code here to tear down your application
        }
    }
    

在ViewController中:

import Cocoa

class ViewController: NSViewController, NSTextDelegate {

   @IBOutlet weak var label: NSTextField!
   @IBOutlet weak var label2: NSTextField!
   @IBOutlet weak var textField: NSTextField!
   @IBOutlet weak var textField2: NSTextField!

   override func viewDidLoad() {
      super.viewDidLoad()
   }

   override func controlTextDidChange(notification: NSNotification) {
      if let txtFld = notification.object as? NSTextField {
         switch txtFld.tag {
         case 201:
            self.label.stringValue = txtFld.stringValue
         case 202:
            self.label2.stringValue = txtFld.stringValue
         default:
            break
         }
      }
   }
}

我知道不久前有人回答了这个问题,但我最终在 Swift 3 中找到了这个适用于 macOS 的解决方案(不幸的是,它不适用于 Swift 4),它会在文本字段出现时发出通知在内部单击并为每个击键单击。

将此代表添加到您的 class:-

NSTextFieldDelegate

在viewDidLoad()中

NotificationCenter.default.addObserver(self, selector: #selector(textDidChange(_:)), name: Notification.Name.NSTextViewDidChangeSelection, object: nil)

然后添加这个功能:-

    func textDidChange(_ notification: Notification) {
        print("Its come here textDidChange")
        guard (notification.object as? NSTextView) != nil else { return }
        let numberOfCharatersInTextfield: Int = textFieldCell.accessibilityNumberOfCharacters()
        print("numberOfCharatersInTextfield = \(numberOfCharatersInTextfield)")
}

希望这对其他人有帮助。

以上答案不适用于 swift 4 所以,

Swift4

的解决方案

过程基本相同,但您只需将一些功能扩展到 NSTextfield Class。我们必须这样做的原因是像 controlTextDidChange: 这样的委托协议方法实际上根本不存在,因为 objective-c 代码的旧设计没有映射好到 swift。 objective-c 中的 NSTextFieldDelegate 是一个非正式协议,与 swift 中的扩展相同。

例子

extension NSTextField{ func controlTextDidChange(obj: NSNotification){} }

class SomeViewController:NSViewController,NSTextFieldDelegate {

override func controlTextDidChange(_ obj: Notification)
{
    let object = obj.object as! NSTextField
    let value = object.stringValue
    print(value)
}

对于每个函数,您想要从 NSTextFieldDelegate 使用,只需将方法放在扩展子句中即可。

swift 5 xcode 10

//TODO: move oin a better place?
extension NSTextField{ func controlTextDidChange(obj: NSNotification){} }


    class TracksController:NSViewController,
        NSTextFieldDelegate
    {
...
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        //Search bar:
        self.searchBar.delegate = self

        NotificationCenter.default.addObserver(self,
                                               selector: #selector(controlTextDidChange(_:)),
                                               name: NSTextView.didChangeSelectionNotification,
                                               object: nil)

    }

//标记:NSTextFieldDelegate

func controlTextDidChange(_ obj: Notification)
{
    guard let object = obj.object as? NSTextView else{
        return
    }


    let delegate = object.delegate
    guard  let searchField = delegate as? NSSearchField else {
        return
    }

    let text = searchField.stringValue
    print(text)

}