0

Currently I am having multiple textfields in a view. If the user taps at one of them there should be a function responding to the event. Is there a way on how to do react (if a textfield got the focus)? I tried it with the NSTextFieldDelegate method but there is no appropriate function for this event.

This is how my code looks at the moment:

class ViewController: NSViewController, NSTextFieldDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        let textField = NSTextField(frame: CGRectMake(10, 10, 37, 17))
        textField.stringValue = "Label"
        textField.bordered = false
        textField.backgroundColor = NSColor.controlColor()
        view.addSubview(textField)

        textField.delegate = self

        let textField2 = NSTextField(frame: CGRectMake(30, 30, 37, 17))
        textField2.stringValue = "Label"
        textField2.bordered = false
        textField2.backgroundColor = NSColor.controlColor()
        view.addSubview(textField2)

        textField2.delegate = self

    }

    func control(control: NSControl, textShouldBeginEditing fieldEditor: NSText) -> Bool {
        print("working") // this only works if the user enters a charakter
        return true
    }

}

The textShouldBeginEditing function only handles the event if the user tries to enter a character but this isn't what I want. It has to handle the event if he clicks on the textfield. Any ideas, thanks a lot?

Edit

func myAction(sender: NSView)
{
    print("aktuell: \(sender)")
    currentObject = sender
}

This is the function I want to call.

Tom el Safadi
  • 6,164
  • 5
  • 49
  • 102

2 Answers2

1

1) Create a subclass of NSTextField.

import Cocoa

class MyTextField: NSTextField {

    override func mouseDown(theEvent:NSEvent) {
        let viewController:ViewController = ViewController()
        viewController.textFieldClicked()
    }
}

2) With Interface building, select the text field you want to have a focus on. Navigate to Custom Class on the right pane. Then set the class of the text field to the one you have just created.

3) The following is an example for ViewController.

import Cocoa

class ViewController: NSViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }

    override var representedObject: AnyObject? {
        didSet {
        // Update the view, if already loaded.
        }
    }

    func textFieldClicked() -> Void {
        print("You've clicked on me!")
    }
}

4) Adding text fields programmatically...

import Cocoa

class ViewController: NSViewController {

    let myField:MyTextField = MyTextField()

    override func viewDidLoad() {
        super.viewDidLoad()

        //let myField:MyTextField = MyTextField()
        myField.setFrameOrigin(NSMakePoint(20,70))
        myField.setFrameSize(NSMakeSize(120,22))
        let textField:NSTextField = NSTextField()
        textField.setFrameOrigin(NSMakePoint(20,40))
        textField.setFrameSize(NSMakeSize(120,22))
        self.view.addSubview(myField)
        self.view.addSubview(textField)
    }

    override var representedObject: AnyObject? {
        didSet {
        // Update the view, if already loaded.
        }
    }

    func textFieldClicked() -> Void {
        print("You've clicked on me!")
    }
}
El Tomato
  • 6,479
  • 6
  • 46
  • 75
  • Can I also set the class of the textfield programmatically and within the mouseDown event I also need a reference to the textfield... – Tom el Safadi May 28 '16 at 02:01
  • I don't know about setting the class of a text field to the subclass you have. You may have to add a text field to the view programmatically. – El Tomato May 28 '16 at 02:07
  • Sorry I explained it wrong. In my code example above you can see that I am adding a textfield programmatically, so I can't navigate to custom class in the interface builder (step 2 of your answer). So do you know how to do this step programmatically? – Tom el Safadi May 28 '16 at 02:10
  • Perfect! I only need a reference from the textfield which invokes the mouseDownEvent, see my edit. – Tom el Safadi May 28 '16 at 02:19
  • What did you edit? How do I get the reference out of the mouseDown method? I have done an edit on my question look at the edit. I have to call this function... Do you know how to get a reference of the textfield calling the mouseDown method? @ElTomato – Tom el Safadi May 28 '16 at 02:36
  • Will accept your answer:) very good support from you!! Thanks a lot, I only need the reference – Tom el Safadi May 28 '16 at 02:37
  • See the line let myField:MyTextField = MyTextField(). myField is the reference. – El Tomato May 28 '16 at 02:39
  • Ahh no I need the reference in the mouseDown method so That I can know which of the many textfields called it – Tom el Safadi May 28 '16 at 02:40
0

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() add these:-

imputTextField.delegate = self

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.

Andy
  • 107
  • 1
  • 8