How to live check a NSTextField - Swift OS X

假如想象 提交于 2019-12-01 19:26:43
  1. Conforms ViewController to protocol NSTextDelegate.
  2. Assign ViewController as Delegate for TextField.
  3. Implement controlTextDidChange method.

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

in 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
         }
      }
   }
}

I know it’s been answered some while ago but I did eventually find this solution for macOS in Swift 3 (it doesn’t work for Swift 4 unfortunately) which notifies when a textfield is clicked inside and for each key stroke.

Add this delegate to your class:-

NSTextFieldDelegate

In viewDidLoad()

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

Then add this function:-

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

Hope this helps others.

The answers above dont work for swift 4 so,

Solution for Swift 4

The process is mostly the same but you just have to extend some functionality to the NSTextfield Class. The reason we have to do this is that the delegate protocol methods like controlTextDidChange: actually don't exist at all because of the old design of objective-c code that doesn't map well to swift. The NSTextFieldDelegate in objective-c is an informal protocol which is the same thing as an extension in swift.

Example

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

For every function, you want to use from the NSTextFieldDelegate just put the method in the extension clause.

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)

    }

//MARK: 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)

}

You can use NSNotificationCenter to observe your text field.

@IBOutlet weak var textField: UITextField!

In viewDidLoad()

let noti = NSNotificationCenter.defaultCenter()    
noti.addObserver(self, selector: "textDidChange:", name: UITextFieldTextDidChangeNotification, object: textField)

And then define a function, such as:

func textDidChange(noti: NSNotification) {
    print(textField.text)
}

now each keystone you enter in text field, it will be printed out in textDidChange() function.

Hope this help

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!