I'm having a bit of a strange issue that I can't quite figure out. I'm somewhat of a n00b to Interface Builder. What I am trying to do seems like it should be simple, but it's not working for some reason.
In interface builder I have a preferences window with a simple NSTextField. I have set the value binding to the Shared User Defaults Controller with the controller key "values" and model key "test". I build/run my app and open the preferences window, type some random value into said text field, close the window. Command-Q the app. Then in a shell i do a "defaults read com.xxx.yyy" for my app and the key and value are nowhere to be found. That being said, it seems like the next time I fire up the app and change the value it works but only if I switch focus off of the NSTextField before closing the window.
In the documentation for NSUserDefaults it says that the shared controller saves values immediately, am I missing something stupid here?
Thanks for any help.
I'm answering this a long time after it was asked in case others find it useful.
It sounds like you need to set "Continuously Updates Values" for the text field you've bound. Otherwise, the value is only sent and, accordingly, the preferences only updated when something happens to 'finalise' the edit. That's usually triggered by pressing Return and probably also happens when you switch focus away from the window (though I just tested this in one of my own applications and it didn't seem to commit the edit).
Related
The NSTableView has a feature, called Type Selection, by which the user can type the first letters of a listed item and the view automatically selects the first hit and scrolls to it.
I like to have a similar functionality in a NSCollectionView, where I list images by name.
Before I start writing such code by myself, I wonder if there is an API that can help me with this.
I am especially worred about getting the timing right, as I want to have it use the same timing as the NSTableView does. I imagine that it even changes depending on the user's System Preferences for typing. Also, the NSTableView will select other items with the same typed prefix if waiting long enough. All this can get quite complicated if I want to get it right. I don't want to miss anything.
I have a simple form (NSWindow) with 3 text fields. NSWindow's initialFirstResponder is 'pointing' to the first field (NSTextField). All three text fields are circularly linked to each other via nextKeyView.
Problem that I have is that when I start the application from Xcode it'll focus on the text field that was last active (in focus) when the application closed.
So for example, if I name text fields A, B and C and initialFirstResponder is set to A. Now if I start the application, focus on B, and close the application, next time I start it, the focus will be on B.
Why is that and how would I fix this?
(Sorry if this is a trivial question, these are my first steps in cocoa...)
EDIT:
This is on OS X Lion 10.7.1, Xcode 4.1.
EDIT 2:
I found a way to "fix" this... In the main window (or any window for that matter) XIB/NIB file, click on "Attributes Inspector", then uncheck "Restorable" box. Now the application will not store the last position and so the initialFirstResponder seeing will be respected and followed accordingly.
Welcome to Cocoa! :) I suspect this is happening as part of the new user interface preservation features in OS X Lion. (In fact, I just created a simple app with 3 text fields, and I see this behavior too.) Because windows automatically restore themselves, you will see a lot of this behavior happening automatically even if you didn't implement it. This is probably desirable — most applications will work this way, and the user will come to expect it.
However, if you really want to disable it, you can probably do so by subclassing NSWindow or perhaps NSTextField and overriding -encodeRestorableStateWithCoder:. But, I definitely recommend you leave the default behavior alone.
Edit with a little further information: the app state seems to be stored in ~/Library/Saved Application State/com.yourapp.savedState. There you can see a plist file with information about the windows. The other files don't seem easily readable, but they probably contain information about which field is first responder, etc.
Despite this thread being almost 10 years old I'll gonna add an answer. Just about one month after the answer from jbandes OS X 10.7 Lion was introduced.
Following a quote from NSWindowRestoration.h
#interface NSWindow (NSUserInterfaceRestoration)
/* Determines whether the window should be restored on relaunch. By default, windows with NSTitledWindowMask set in the styleMask are restorable, and windows without it set are not.
*/
#property (getter=isRestorable) BOOL restorable API_AVAILABLE(macos(10.7));
I have an NSMenuItem for which I would like to use the key equivalent Command-Option-C. However, when I set the key equivalent in IB, it does not get associated with the menu item when the app is actually run. The entry has no visible key equivalent, and that command does not invoke the item. Other key equivalents, like Shift-Control-C, do indeed work. The one I am trying to use does not conflict with any other key equivalent in the app.
What could be causing this seemingly random problem?
Command-Option-C works just fine here. Could it be that you have a custom keyboard shortcut set up in the keyboard system preferences that uses the same key combination? That would override the application's own shortcuts.
Is it possible the menu item in question is a "special" menu item which may be getting substituted at launch-time by the system? If so, it would be helpful to know whether you are able to set the same keyboard shortcut on a different, perhaps less interesting menu item.
I don't really have an authoritative understanding of which menu items may get this kind of treatment, but have a suspicion for example that maybe the "Help" menu, "Application" menu, or others that are common across many apps get tweaked or even regenerated dynamically, altering what you specified in the nib.
The easiest workaround I would shoot for first is to call setKeyEquvialent: directly on the menu time from code, after the nib has loaded. I couldn't tell from your Twitter summary if you had already tried this, and it also failed.
Check the tag on your menu item. If set to certain values it might Cocoa to override stuff
Check your system Prefs aren't overriding key bindings
Check the key binding doesn't already exist elsewhere in the menu hierarchy, especially in the edit menu
Okay, I'm fairly new to Cocoa and Objective-C, and to OOP in general.
As background, I'm working on an extensible editor that stores the user's documents in a package. This of course required some "fun" to get around some issues with NSFileWrapper (i.e. a somewhat sneaky writing and loading process to avoid making NSFileWrappers for every single document within the bundle). The solution I arrived at was to essentially treat my NSDocument subclass as just a shell -- use it to make the folder for the bundle, and then pass off writing the actual content of the document to other methods.
Unfortunately, at some point I seem to have completely screwed the pooch. I don't know how this happened, but closing the document window no longer releases the document. The document object doesn't seem to receive a "close" message -- or any related messages -- even though the window closes successfully.
The end result is that if I start my app, create a new document, save it, then close it, and try to reopen it, the document window never appears. With some creative subclassing and NSLogging, I managed to figure out that the document object was still in memory, and still attached to the NSDocumentController instance, and so trying to open the document never got past the NSDocumentController's "hmm, currently have that one open" check.
I did have an NSWindowController and NSDocumentController instance, but I've purged them from my project completely. I've overridden nearly every method for NSDocument trying to find out where the issue is. So far as I know, my Interface Builder bindings are all correct -- "Close" in the main menu is attached to performClose: of the First Responder, etc, and I've tried with fresh unsullied MainMenu and Document xibs as well.
I thought that it might be something strange with my bundle writing code, so I basically deleted it all and started from scratch, but that didn't seem to work. I took out my -init method overrides, and that didn't help either. I don't have the source of any simple document apps here, so I didn't try the next logical step (to substitute known-working code for mine in the readFromUrl and writeToUrl methods).
I've had this problem for about sixteen hours of uninterrupted troubleshooting now, and needless to say, I'm at the end of my rope. If I can't figure it out, I guess I'm going to try the project from scratch with a lot more code and intensity based around the bundle-document mess.
Hard to tell without code but I would suggest sending:
closeAllDocumentsWithDelegate:didCloseAllSelector:contextInfo:
... to the document controller and then looking at the controller as it is passed to the delegate to see how its state changes.
If the controller closes the document when you send the explicit message then your problem is with the binding to the window.
I'm using the Cocoa Accessibility API to try and modify the value of a text field (AXTextField) in another application, but I've run into a problem: my code correctly identifies and modifies the contents of the text field in question, and the text of the field visibly changes, but the changes aren't registered by the program I'm trying to control. Is there a way to do this in with the API without having to generate keyboard events?
Sample code:
AXUIElementCopyElementAtPosition(appRef,
clickPoint.x,
clickPoint.y,
&boxRef);
NSString *valueToSet = [NSString stringWithFormat:#"%f",amount];
AXUIElementSetAttributeValue(boxRef,kAXValueAttribute,valueToSet);
And the text field changes to the value specified in "amount" but the other program doesn't recognize the change - I have to go type the number in myself to get it to pick up the change (I can tell the difference, because the program responds when a new value is typed in the box). Can anyone point me in the right direction?
For posterity: Informed sources tell me that this is actually a bug in the application I'm trying to control. You can tell the difference by using UI Browser (http://prefabsoftware.com/uibrowser/) to try and set the value of the textfield; if UI Browser can't make the change stick, then the matter is out of your control.
Try telling the text field:
perform action "AXConfirm"
This is Applescript, but whatever the Cocoa equivalent is, it may make the change stick even if UI Browser can not (I've used it before).