0

On a OSX app I have 3 NSTextField and 2 NSButtons

@IBOutlet weak var TF1: NSTextField!
@IBOutlet weak var TF2: NSTextField!
@IBOutlet weak var TF3: NSTextField!
@IBOutlet weak var Bt1: NSButton!
@IBOutlet weak var Bt2: NSButton!

Bt1 will write on the selected textfield "Button 1 Pressed"
Bt2 will write on the selected textfield "Button 2 Pressed"

But I haven't found how to detect which NSTextField is selected. Does anyone have a sample code/example on this?

Edit:

2 solutions works perfectly
Thanks to @MwcsMac and @sfjac

@IBAction func test(_ sender: NSButton) {
    var textField : NSTextField? = nil
    // the focused control is the first responder of the window
    let responder = sender.window?.firstResponder
    // if a text field is focused, the first responder is the field editor, a NSTextView
   if let textView = (responder as? NSTextView) {
        if textView.isFieldEditor {
            // the focused text field is the delegate of the field editor
            textField = textView.delegate as? NSTextField
        }
    }
    else {
        if responder is NSTextField {
            textField = responder as? NSTextField
        }
    }
    textField?.stringValue = "test"
}

and

    @IBAction func Bt1Pressed(_ sender: NSButton) {
    if isTextField(inFocus: TF1){
        TF1.stringValue = "B1 Pressed"
    }
    if isTextField(inFocus: TF2){
        TF2.stringValue = "B1 Pressed"
    }
    if isTextField(inFocus: TF3){
        TF3.stringValue = "B1 Pressed"
    }
}

@IBAction func Bt2Pressed(_ sender: NSButton) {
    if isTextField(inFocus: TF1) {
        TF1.stringValue = "B2 Pressed"
    }
    if isTextField(inFocus: TF2){
        TF2.stringValue = "B2 Pressed"
    }
    if isTextField(inFocus: TF3){
        TF3.stringValue = "B2 Pressed"
    }
}

func isTextField(inFocus textField: NSTextField) -> Bool {
    var inFocus = false
    inFocus = (textField.window?.firstResponder is NSTextView) && textField.window?.fieldEditor(false, for: nil) != nil && textField.isEqual(to: (textField.window?.firstResponder as? NSTextView)?.delegate)
    return inFocus
}
Community
  • 1
  • 1
Rombond
  • 129
  • 2
  • 11
  • 1
    Possible duplicate of [How to detect when NSTextField has the focus or is it's content selected cocoa](https://stackoverflow.com/questions/25692122/how-to-detect-when-nstextfield-has-the-focus-or-is-its-content-selected-cocoa) – koen Jan 29 '18 at 17:58
  • @Koen i know but i'm really bad in Objectives-C so i havn't understand the answer – Rombond Jan 29 '18 at 18:59
  • You don't have to translate Objective-C to Swift. Recognize which method is called and do the same in Swift. But your question is not a duplicate, the linked question is about getting notified. Do you want to check if a text field is focused or do you want to get the focused text field? – Willeke Jan 30 '18 at 08:47
  • @Willeke i want to get which textfield is focused to write in – Rombond Jan 30 '18 at 17:20

3 Answers3

2

This should give you the result you are looking for. This is tested on Xcode 9.2 and on macOS 10.13.3.

@IBAction func Bt1Pressed(_ sender: NSButton) {
    if isTextField(inFocus: TF1){
        TF1.stringValue = "B1 Pressed"
    }
    if isTextField(inFocus: TF2){
        TF2.stringValue = "B1 Pressed"
    }
    if isTextField(inFocus: TF3){
        TF3.stringValue = "B1 Pressed"
    }
}

@IBAction func Bt2Pressed(_ sender: NSButton) {
    if isTextField(inFocus: TF1) {
        TF1.stringValue = "B2 Pressed"
    }
    if isTextField(inFocus: TF2){
        TF2.stringValue = "B2 Pressed"
    }
    if isTextField(inFocus: TF3){
        TF3.stringValue = "B2 Pressed"
    }
}

func isTextField(inFocus textField: NSTextField) -> Bool {
    var inFocus = false
    inFocus = (textField.window?.firstResponder is NSTextView) && textField.window?.fieldEditor(false, for: nil) != nil && textField.isEqual(to: (textField.window?.firstResponder as? NSTextView)?.delegate)
    return inFocus
}
MwcsMac
  • 6,810
  • 5
  • 32
  • 52
2

Here's what I do in Objective-C:

id responder = [window firstResponder];
if (responder && [responder isKindOfClass:[NSTextView class]] && [responder isFieldEditor])
    responder = [responder delegate];
if ([responder isKindOfClass:[NSTextField class]])
    [responder setStringValue:@"test"];

and my (probably clumsy) translation to Swift:

@IBAction func test(_ sender: NSButton) {
    var textField : NSTextField? = nil
    // the focused control is the first responder of the window
    let responder = sender.window?.firstResponder
    // if a text field is focused, the first responder is the field editor, a NSTextView
    if let textView = (responder as? NSTextView) {
        if textView.isFieldEditor {
            // the focused text field is the delegate of the field editor
            textField = textView.delegate as? NSTextField
        }
    }
    else {
        if responder is NSTextField {
            textField = responder as? NSTextField
        }
    }
    textField?.stringValue = "test"
}
Willeke
  • 14,578
  • 4
  • 19
  • 47
-1

Your textfield with the focus will be the firstResponder. You can check for that and then execute your code:

if myNSWindow.firstResponder == TF1 {
  // Do something with TF1
}

(pseudo-code, typed in browser, not tested with Xcode)

koen
  • 5,383
  • 7
  • 50
  • 89
  • I don't mind a down vote, but could you explain why, so I can try to improve my answer? – koen Jan 31 '18 at 13:30