How can I save NSWindow programmatically? - objective-c

Basically I got an array of allocated windows and want to save their state (position/size/subviews) when the app is closed. Is there any way to do this?
When I try to use a NSUserDefault i get this error message: Attempt to set a non-property-list. Which turns out to that you can't save NSWindows in a user default. Should i use this instead?
//customView
[self setFrameAutosaveName:[NSString stringWithFormat:#"%d",self.tag]];

It's not usually useful to save the positions and size of subviews in a window.
Using setFrameAutosaveName: will save the window's position and size for a given name. The next time your app opens a document and creates a window with that autosave name, its state should be restored.
As for the size and positions of subviews, they are usually automatically laid out based on the auto layout system, or using Struts and Springs. Either that, or their positions and sizes are derived from data in your document model. Either way, you don't generally need to save them yourself. Why do you think you should be saving them? What are you trying to accomplish by saving them?

Related

Getting window restored bounds

When you maximize a window in Macos, the window fills the screen.
What I want to be able to do is get the windows restored position and size, like when you press the maximize button again to restore the original position. How can you do this?
I need this for saving the window position on exit.
There is a method prepared for this task in NSWindow.
You could ask your ViewController for its NSWindow and set an AutosaveName for its Frame like..
[self.view.window setFrameAutosaveName:#"VerySpecialWindowAutoSaveName"];
which will end up in NSUserDefaults of your App as entry like...
"NSWindow Frame VerySpecialWindowAutoSaveName" = "300 100 1200 1005 0 0 2560 1289"
But the best place for this code is ... there is no best place because it depends on your apps approach.
The whole process can be challenging when you have multiple windows in a document based application but as you can set the AutosaveName per documents window you are able to recover the frame if needed, at least for the last document. Should be mentioned that you can set the AutosaveName in InterfaceBuilder and in Code as well - so keep an eye on it they follow the same name if you use both IB & code for one and the same window.
and an example in swift you can find in this gist

Save NSWindow Size on Resize & Close For User

I've noticed that all applications on OS X seem to save the size you set it at. The next time you open it it's typically in the same position and size.
I'm making an app and I've noticed that after resizing, if I launch the application again it's just the size of what I've set in Xcode 4's IB and not the size that I resized it to on launch.
Do I have to manually save the window size each time its changed? Or is there an easier way to do this through IB? (My window does have a minimum size set if that changes anything.)
Apple makes it easy. In interface builder, for your window, just type in a unique name in the Autosave field and it will save it under that name in the global user defaults. E.G.
When you select your main window in the Interface Builder, there should be a property called Autosave in the attributes inspector. Put any name in there does the trick for me.
After setting the Autosave name in IB I could see that my window's frame was being saved to its preferences file, but still the auto restore would not work. Then I remembered to uncheck the Close windows when quitting an app checkbox in the System Preferences under the General settings, and the window position restored as expected.
If you did not use IB to create your window, you can set this property in Swift using:
setFrameAutosaveName(_ name: NSWindow.FrameAutosaveName)
(the frameAutosaveName property is get only)
For example:
windowController.window?.setFrameAutosaveName("appWindow")

Cocoa: how to reference lots of NSSliders

I have this xib file for my main window, and it contains 64 sliders to be able to create a matrix mix for an audio application.
Setting the values using the sliders works, but I also want to save the values to the default preferences and load them back in the next time the application is started.
I have this working, but the sliders are not representing the actual values when the preferences are loaded.
How would i do this, without having to create 64 IBOutlets in my app controller?
I have the actual values in a NSMutableArray.
Maybe an outlet collection will help you?

How do I use an indeterminate status indicator as the image for an NSStatusItem?

I have an application that is an NSStatusItem.
It has a few different modes, each of which require an external process to be launched, during which the icon is simply highlighted, and appears to be frozen.
I want to use the -setImage: method (or reasonable facsimile) to display something along the lines of a "spinner" commonly seen in web applications and all over OS X.
Is there any native method for accomplishing this (e.g. some instance of NSProgressIndicator?) or must I manually display an animation by cycling through a set of images?
In either case, how would I implement?
In order to have it be animated (and not just a static image), you'll probably need to use -setView: and give it a custom view (which then animates itself). You might be able to get away with using a suitably-configured standard NSProgressIndicator (i.e. set to NSProgressIndicatorSpinningStyle style, etc.) as that "custom view".
But, if the NSProgressIndicator standard sizes don't work well, then you can check out my YRKSpinningProgressIndicator (BSD-licensed), which is a clone of the spinning NSProgressIndicator that can be set to arbitrary size and colors.

Cocoa question for displaying images

I was wondering if anyone could tell me if there is a method in Cocoa that will display information (images) on screen when a button is pressed. What I mean is NSLog "prints text" to the console is there a method that displays images just as easily like would -(void)drawView do it? Is it just setNeedsDisplay? I hope this makes sense. I am essentially wanting to know if I can call something that will display an image as easily as you can display/print text to the screen/console.
The Console is text-only, so no, you can't print an image to it the same way you log text. The closest equivalent is to export the image as TIFF data and write that data to a file in the temporary directory.
As for setNeedsDisplay:, that tells AppKit that the view should be told to redraw the next time the window redraws its views. (In other words, it sets the view as needing display—exactly what it says on the box.) Usually, this is because you've changed the model object(s) that the view displays, either by replacing them with other objects or by mutating one or more of their properties.
You would need to have a view to display; an image view would certainly qualify, but if you're looking for the image equivalent to NSLog, this isn't it, unless you don't mind either making a dedicated window just for showing this image or temporarily putting a image view into one of your real windows.
You should take a look at Apple's NSImageView Class Reference.
This a class you can use to display an image in Cocoa.
setNeedsDisplay is a NSView method that tells the graphics renderer it needs to redraw the image because the data has been modified. Presumably because you are using something like Quartz and you have called some custom drawing code. If you are drawing bitmap images then you probably won't need to use this.