OSX Cocoa using tab to navigate between child controls within a view not working - objective-c

I am new to Xcode/OSX UI so there is probably something silly I'm overlooking. This is XCode 5.11 targeting OSX 10.10 desktop.
I have inherited some code with a few views where navigating among child controls within the view using the tab key does not work.
In researching this almost everything says to be sure to set the first responder and then chain your controls using nextKeyView.
I followed the steps in this video https://www.youtube.com/watch?v=SRrE8eqp0dU (XCode 4, but all the functionality seemed to be the same for 5.11) to no avail.
I also had a look at this solution How to make child controls of view will get focus on Tab and Shift+Tab in NSViewController which sounds like a similar issue to what I am seeing, but one of the classes I inherited uses NSWindowController vs. NSViewController as the base and there is no loadView to override and the other which did derive from NSViewController did not behave any differently with the changes made to loadView.
When my window launches my first responder control (NSTextField in this case) has focus (blue highlight) but tab key is ignored and focus will not change unless I use the mouse.
So it's really not a tab ordering issue initially, it seems like a tab ignored issue and who knows what the ordering is. I tried setting focus to a NSButtonCell and NSPopUpButton using the mouse and then tab navigate from those to see if there was some issue with my NSTextField but they exhibit the same behavior. None of the controls are set to "Refuses First Responder" which was another setting it was recommended to check.
I'm at a loss and looking for any other things to try or check.
The first view I am having an issue with is: Window / Child View / Multiple Child Boxes / Multiple controls per box in case that matters or complicates things. It is basically for setting application Preferences.
The second view seems like it may be more complicated in that there is a single Window that swaps out its child view in a next/back progression (wizard interface). The initial window nib is "blank" so I didn't see how to associate a first responder from IB like I did with the Preferences window since all the controls are on their own individual view nibs (these all show as "Custom View" vs. just "View" for Preferences).

The resolution for me was to ensure that the "Auto Recalculates View Loop" setting in the Attributes Inspector was enabled for the windows hosting these views. This corresponds to the autorecalculatesKeyViewLoop property of NSWindow.

Related

Using multiple windows with Storyboards (Mac OS X development)

I have two window controllers (with their own view controllers) on a storyboard.
In one window, I have the main program, a basic text editor with an NSTextView. In the other window, I have a single button.
I found out how to get the window to display by linking it to a menu item. It works.
The main window is linked to my ViewController class by default. The second window is also linked to the ViewController class and has its button linked to an IBAction in the ViewController class.
I have some simple code in the IBAction that basically tells the NSTextView to change its font size to a much bigger font. I have confirmed that the code itself works when called in other methods.
The button works, BUT it is using an entirely different instance of my ViewController class. So in result: the text size doesn't change.
So my main question here is how do I get an IBAction in one window to affect an object in another window.
I hope I did an alright job at explaining myself. Keep in mind this is my first Stack Overflow question:) I tried my best to research this question but mostly found information on iOS development and using XIB files.
It sounds like you have two windows with the same controller class but want what happens in one window to affect the other window. The easiest way is going to be with notifications. When the button is clicked in one window a notification gets posted that all instances of ViewController receive and respond to by changing the font size as needed. You could also look into setting a user default when the button is clicked and using bindings to keep the text field's font size tied to the current default.

NSWindow levels and modal dialogs

I have an application that needs to display a window on top of anythings else. To achieve this I call [window setLevel:NSStatusWindowLevel] on my main window.
This works fine except that I can't use any modal dialogs or alerts from this window. The problem seems to be that [NSWindow beginSheet...] internally calls setLevel: on the target modal window with a value lower than NSStatusWindowLevel, so the modal dialog is displayed behind its parent window. The same happens when using an NSAlert from a window with higher window level, the alert is displayed behind.
The only [ugly] workaround I found is to inherit NSWindow, override setLevel: and prevent setting a lower level value on these modal windows but this only works when I have control over the window and doesn't work for NSAlerts.
Is there a more elegant solution for displaying modal dialogs from a NSWindow with high window level value that will also work with NSAlerts? Or I will be unable to use NSAlert with this approach?
one thing that comes to mind is to check if NSAlert uses a special NSWindow subclass you could make a category on it and hook the setLevel: method via swizzling (here is an example of extending an existing method via swizzling). there is nothing stopping you from doing this in a plain NSWindow subclass either.
I know its not the "elegant solution" you'd hoped for, but its the only one I know off the top of my head. I suppose it is slightly more elegant in that you don't have to insert your custom subclass everywhere throughout your program, but less elegant in that you are messing with the objective-c runtime using code that simply seems wrong.

UIBarButtonItem created in Interface Builder not working - confused

I am trying to tidy up my UI by consolidating various things in a Tool Bar, and am utterly confused. I am using Interface Builder rather than constructing the controls programmatically, because my UI is fairly simple and not particularly dynamic.
What I did did so far:
Added an empty tool bar.
Dragged two previously existing and working buttons onto the tool bar. They changed their class from UIButton
to UIBarButtonItem, and the inspector now shows them as having no
Sent Actions or Referencing Outlet, but the the previous action &
outlet in the View Controller - responding to taps, setting the
label of the button - still work.
Created a new Button directly
in the tool bar. Wired up its action & outlet by ctrl-drag in the
normal way. The inspector shows the Action and Outlet for this
button as connected, which is nice, but sadly neither of them works.
Clicking the button does not invoke the action; setting the label of
the button does not cause anything to happen on the screen, even
after I tried prodding the tool bar with a setNeedsDisplay.
I'm not sure what to try next. Googling has shown me that I'm not the only person to find using UIToolBar via Interface Bulder difficult and confusing, but I haven't found a solution to my exact problem.
I don't particularly want to resort to creating my entire GUI programmatically just to tidy up a few buttons. Creating all the controls in Interface Builder outside the tool bar, getting them wired up and working, then moving them into the tool bar would presumably also work - but it would be a kludge, and would leave me still none the wiser if anything went wrong later.
Should you try using UIBarButtonItem instead of UIButton? It works for me.
i had a similar issue.
Did you created an extra UITapGestureRecognizer for root view ?
Maybe for something like > When elsewhere than UITextView clicked, resignFirstResponder for all UITextViews !
In my case, on 7.1, that extra UITapGestureRecognizer prevented transfer of event to IBAction of UIBarButtonItem which is inside an UIToolBar.
IBAction was made on Storyboard by Ctrl+Drag.
on 8.1 it was working. Not on 7.1
Read some suggestions to create an extra UIView and putting all visual elements into that extra UIView except UIToolBar

How to check if a NSWindow is visible

Is there a way to check if a NSWindow is visible or not? I want to display a sheet controller once the first window of my app became visible (the animation on 10.7 ended and the user can see the window!). If I just show the sheet in windowDidLoad, it results in a stupid looking animation (sheet rolling out, window popping out from the back). I know that NSWindowDelegate provides two methods which are invoked when a window either became the key window or the main window, however, this doesn't have to mean that the window is already fully visible at the time. This is even more noticeable on Lion where windows tend to pop up with this stupid animation.
I would go for something like this:
if ([myWindow isVisible]) {
// Do stuff
}
Or an an observer for this key path to be notified when the change occurs.
For what it's worth, you can also bind to the window.visible property. Xcode 4 may squawk at you, saying it's not a bindable property, but it will work.
This can be useful if you are trying enable/disable show/hide NSStatusItem based on whether the window is visible, as well as other approaches.
i.e. in Interface Builder:
Bind to: App Delegate
Model Key Path: self.window.visible

Drawing an "NSView" to a Custom-View - How? Am I taking the right approach?

I'm using Objective-C and Cocoa, whilst developing for Mac OS X - so not the iPhone/Cocoa Touch. (That said, I'd be interested if it was the same procedure for the iPhone)
I'm working on a preferences window for a simple app. I have a NSWindow with a toolbar - there are 5 different items on the toolbar, all of which need to bring up a different set of options.
So I set the NSToolbar and its items in Interface Builder, and then placed a custom view underneath the menu - taking up the rest of the window. My plan is to work out the interface too each of the NSToolbarItems options, and then draw the corresponding view on to the custom view when the specified NSToolbarItem is clicked.
I'm guessing that I simply create a NSView sub-class for each view, an empty xib in Interface Builder - set the xib to my custom NSView, code it as usual... But here's a few problems;
1 - Just how can I get the xib file to appear on the custom-view then? I have looked around and most articles don't seem to have this situation, or a situation I can relate too.
2 - When the window comes up, I want the default view to appear on the custom view. Once again, I'm guessing I just write that in the initialisation code for the NSWindow - its no big deal. It just goes back to question 1 though - how do I draw my NSView to the custom-view specified in Interface Builder?
I'd be really grateful for any help!
Cheers in advance.
So I set the NSToolbar and its items in Interface Builder, and then placed a custom view underneath the menu - taking up the rest of the window.
You can't have a menu inside of a window. You can have a pop-up button, which has a menu, but not a menu directly. Did you mean “toolbar” here?
You don't need to create a custom view for this. Make a tab view and set it to be tabless. Give it as many tab view items as you have toolbar items. In your controller, write an action method for each of the toolbar items, and in each action method, switch the active tab of the tab view.
You can activate different tabs in IB to populate them with views in IB. The active tab is saved in the nib, so make sure you set it back to the first tab before saving, so that the first tab is the one that's initially active when your app runs.
Just how can I get the xib file to appear on the custom-view then?
That question doesn't make sense.
Once again, I'm guessing I just write that in the initialisation code for the NSWindow - its no big deal.
You would only be able to do that if you have your own initialization code for the window, which you would only have if you have subclassed NSWindow. There are very few reasons to do that; unless you're making the window itself look different (not making an Aqua or HUD window), you should move that initialization code elsewhere, probably to the aforementioned controller (which should be the File's Owner of the nib).
It just goes back to question 1 though - how do I draw my NSView to the custom-view specified in Interface Builder?
A custom view in Interface Builder is a plain NSView (unless you explicitly change it to a subclass of NSView you create). However, you do not need one for anything you have described in your question.