Removing the Proxy Icon in the bar of my mac app - objective-c

I was wondering how to remove the proxy icon in the bar of my mac app. I've added an image so you can see what Icon I'm talking about
Thank you in advance!

The icon is included in the titlebar of the application automatically when you've created an NSDocument based application.
You can remove the proxy icon by returning nil from the -[NSWindow representedURL] method. This could be accomplished by using a custom NSWindow subclass with the method overridden; or simply setting the property to nil at the appropriate times.
Be aware, you might loose other functionality you normally get for free by changing this behavior, such as the dirty/clean indicator for the window, or some prompting to save when closing the window.
Alternatively, if you wanted a different image, you could use:
[[NSWindow standardWindowButton:NSWindowDocumentIconButton] setImage:customImage]
Then implement -[id<NSWindowDelegate> window:shouldPopUpDocumentPathMenu:] to return NO to prevent the popup menu from appearing.
If your application isn't actually document based, or the window doesn't represent a document, consider refactoring to present this window a different way, rather than being a document window.
There is some additional information in the Cocoa window documentation.

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.

Change Icon of Running Application via NSRunningApplication? What's the setter?

I'm new to this objective-c (1 week)
What is the setter called for the icon property via NSRunningApplication?
Where can i find this in the docs just for my future reference so everytime i need to learn a setter i dont have to ask. :)
I noticed in docs [[NSRunningApplication currentApplication] icon] is a property. Is it possible to set this icon property? Will it change the icon used in dock and the mini icon shown in the minimized window? I point out the mini icon in minimized windows in this image below:
There is no setter. The icon property of NSRunningApplication is readonly.
NSRunningApplication can sometimes refer to the current application, but it's more general than that. It can also refer to other applications on the system. It wouldn't be alright for any application to be able to set the icon of any other application, would it?
Anyway, you want to be working with the main application object of the process, which is the instance of NSApplication. You can get access to that object using [NSApplication sharedApplication]. You can also use the global variable NSApp.
NSApplication has an applicationIconImage property that's read-write. Setting that is the easiest way to change the application's icon.
Alternatively, you can obtain the application's dock tile object (an instance of NSDockTile) using the dockTile property. You can then set a custom view for the dock tile's contentView and that view can render however you want it to. (You can use an NSImageView if you just want to display an image.)
Unfortunately, neither of these approaches will change the badge on the icons of minimized windows (although the class overview docs for NSDockTile say it will). There's not a direct way to do that. You can obtain the dock tile of a minimized window and set a custom view, but then you're responsible for drawing everything about it. There's no way to just change or replace the badge part.

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

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.

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.

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