Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting initialFirstResponder in a storyboarded OSX app

Similar to this question, I'm trying to set the first responder to the first of three NSTextFields in a very simple app. The advice there (set the Window's first responder in interface builder) doesn't seem to apply anymore, at least not when Storyboards are involved. The Window object does indeed have an initialFirstResponder outlet, but I can find no way of setting it via drag, ctrl-drag etc., in either direction to/from the NSTextField.

The structure IB has provided me with comprises a Window Controller Scene (itself just an empty window) linked to a View Controller Scene (which in turn contains my set of NSTextFields and labels).

My suspicion is that there's some default assumption/association that Xcode's baked into my app that causes the Window controller to automatically load a particular view at runtime, and that's why it's not possible to bind an initial responder that it doesn't know about at build time. Which then leaves me wondering which lifecycle call on which object is the right point to be calling self.view.window.initialFirstResponder = myTextField before it's too late, and how to most correctly gain access to that object. viewWillAppear or viewDidLoad in the View Controller feel right, but neither seem to reliably have any effect (the initially active NSTextField varies from run to run, sometimes appearing to track code changes, but either times not).

I've posted the code so far on GitHub

like image 918
Chris Avatar asked Jan 23 '16 16:01

Chris


1 Answers

initialFirstResponder is only applied when the NSWindow first appears on the screen. As per the Xcode docs:

`NSWindow initialFirstResponder`
The view that’s made first responder (also called the key view) the first time the window is placed onscreen.

If you want to set something as first responder then you need to invoke:

swift: yourTextField.becomeFirstresponder()

Obj-C: [yourTextField becomeFirstresponder];

Hope the helps!

Ade

edit

I literally shaved your .m down to a few lines:

    #import "ViewController.h"

    @implementation ViewController

    #pragma mark - View lifecycle

    -(void)viewWillAppear{
        [super viewWillAppear];
        //[self.userTextField becomeFirstResponder];
        [self.pathTextField becomeFirstResponder];
    }

    #pragma mark - Connection actions

    - (IBAction)connectClicked:(id)sender {

    }

    - (IBAction)cancelClicked:(id)sender {
        // Tell the app delegate (once we've actually got a pointer to it) that we want to exit
    //    [self.delegate exitApplication];
    }



    @end

My fault! Sorry, viewWillAppear (just before the view actually shows up) is where you put becomeFirstResponder..

Apologies for the mistake!

like image 143
Adrian Sluyters Avatar answered Sep 18 '22 15:09

Adrian Sluyters