Make specific NSTabViewItem have focus depending on context

I have a custom NSTabViewController displayed from within an NSPopOver and as you can see from the image below, the NSTabViewItems contain custom NSButtons. My issue is that in order to support the latest Accessibility requirements, I would like to have the a specific tab have keyboard focus. Setting InitialFirstResponder does not work. Nor does calling MakeFirstResponder within ViewDidAppear, the normal way. The hack that works for me is within the NSTabViewController's ViewDidAppear override, I do a 250ms delay, on a background thread, and then call MakeFirstResponder on the NSButton I want focus on.


This works as desired, but I'm not fond of hacks, so I'm looking for a more elegant and presumably more correct solution. I'm new to MacOS dev, so looking for the best practice solution, if there is one.


Accepted Reply

We cannot see any image, hence no image below, in the forum.


Instead of putting in viewDidAppear, try to call makeFirstResponder in viewWillLayout or viewDidLayout.

Replies

Looks like my image was stripped from the post. Here is a link to the behaviour in question - https://drive.google.com/open?id=1ef-Rj2NVqyrYxWoaR3YE3IoVmi_ir59Y

We cannot see any image, hence no image below, in the forum.


Instead of putting in viewDidAppear, try to call makeFirstResponder in viewWillLayout or viewDidLayout.

I would put some NSLog statements (print if using swift?) in the viewDidAppear and viewDidLayout so you can verify which one is being called last. That might help you determine where to put the makeFirstResponder. I have found that sometimes it is necessary to put a short delay before calling some things on setup to give everything time to settle in. You might also try

-(void)performSelectorOnMainThread:(SEL)aSelector 
withObject:(id)arg
waitUntilDone:(BOOL)wait;


You might also experiment with putting the makeFirstResponder in the windowDidBecomeKey notification if this part of your code responds to that notification. The windowDidBecomeKey is usually one of the last things to fire when an app and its window is coming up. Keep in mind that this notification will fire each time the window becomes key.


The windowDidLoad might be another place to explore if it is relevant to this part of your code.

If it's too early in viewDidAppear, it will be even worse within windowDidLoad.

Hence my suggestion to use NSLog/print statements to verify and to also explore the possibility of using windowDidBecomeKey if it is relevant to this code.

Setting the Focus in viewDidLayout, seems a much nicer solution. Thanks!