Cocoa: non document based app, array controller bindings? - cocoa

I've looked around and haven't found a clear answer. I'm trying to use an array controller in a non document based app and I can't seem to make it work. Is it impossible to do this?
I'm not sure how to get the content array to bind to the controller. Even a pointer to some reading material would help. Thanks. :)

Of course it's possible -- In IB in the bindings inspector, under the "Content Array" heading choose the class that contains the array you want to bind from the pull down menu, then click the "Bind to" box. In the "Model Key Path" field, type in the property name of your array. That's all there is to it.

Related

How to sort NSArrayController using bindings from NSTableColumn?

There are similar questions to this already, but I haven't found any of them to work for me. All I want to do is re-sort the table view based on clicking the column header. And I don't want to do this programmatically because I don't think I have to. Anyways...
I have a NSTableView binded to an NSArrayController that is binded to my managedObjectContext.
For a specific NSTableColumn, I have the value binded to the Array Controller with the model key path "amount" which is an NSNumber.
I see in the attributes for this NSTableColumn, there is a "Sort Key" and a "Selector". I set the sort key to "value.amount" (not sure why, but I saw this elsewhere) and the selector defaults to "compare:" which seems fine.
Then for the NSArrayController, I see a binding called "Sort Descriptors" which I bind to "Shared User Defaults Controller". The "Controller Key" defaults to "value" (I assume this is why I used value before), and I set the "Model Key Path" to "amount.
This sounds reasonable, I suppose. But (1) it doesn't work and (2) what about when I want to sort based on two different columns? Also, (3) how do I set the default way to sort?
UPDATE:
OK, so I have the array controller binded to the managed object context. I have the table content binded to the array controller arranged objects, and selection indexes to the array controller selectionIndexes. I have a table column value binded to array controller arrange objects and the associated key. the sort key for that column is the same key with a compare: selector.
The table is not reordering when I click the headers though. Am I supposed to bind the sort descriptors of the table?
If possible, can you send me your example?
Thanks for the help,
Chet
First thing you should know is both the NSTableView and the NSArrayController can sort your items. You’re trying to set a mix of both right now, and there’s no point in that. For simple uses, just rely on the tableView.
So, don’t bind anything in the NSArrayController. For the NSTableColumns, don’t use “value.amount”, just use “amount”. “compare:” is fine for the selector.
I just created a tiny project (no code) to demonstrate this and it worked great with sorting.

How do I bind an NSTextField's value to an NSObjectController's content without errors?

I have a pretty simple set up here, and Xcode is giving me a comment-less red "!" mark in the interface builder.
Started from a Core Data-based document template. The document xib has an NSObjectController instance, whose Managed Object Context is bound to the File's Owner (my NSPersistentDocument subclass). An NSTextField is present, whose Value I want to bind to the NSObjectController...and this is where the problem comes in.
I type "title" for the "Model Key Path," because that's the correct property for my NSManagedObject, which should appear in the text field. When I click into the empty Controller Key field, the autocompletion bizarrely suggests fields that are only for NSArrayController:
Any time I try to type "content" as the Controller Key (because that's the correct property for an NSObjectController) and then hit Tab/Return/whatever, the "content" is shifted down to the Model Key Path, like so:
What is this red exclamation mark for? When I leave "Controller Key" empty and "Model Key Path" as content.title, the app works. The binding is correct and reflects the "title" property of my NSManagedObject. I am absolutely sure that "Object Controller" is an instance of NSObjectController.
Use "selection". For an NSObjectController, the selection is the content object.

What are all the things you can bind to in a NSTableColumn of NSPopupButtonCell?

There are quite a few things you can bind to in a NSTableColumn filled with NSPopupButtonCell, I tried looking around for explanations but couldn't seem to find any.
What are each of the binding under value selection for? For example, what's the difference between "Content" and "Content Values"?
Why is "Content Objects" grayed out anyways?
Why do you bind to the table column instead of the Pop Up Button Cell? The binding options available for Table Column containing a TextCell is also different. How is that accomplished?
This should help for general explanations of the bindings
http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/CocoaBindingsRef/BindingsText/NSPopUpButton.html#//apple_ref/doc/uid/NSPopUpButton-DontLinkElementID_801
For help with binding an NSPopupButtonCell and Core Data check out my tutorial at:
http://www.themikeswan.com/blog/?p=81
It will also give you an idea of how the bindings would work for non - Core Data stuff as well.

How to bind objects in NSDictionary in NSUserDefaults?

How do I bind NSDictionary objects to several text fields in Interface Builder?
I would like to bind each object to a specific item in the dictionary. For example, the first text field should be bound to Actor:
You need to add a NSObjectController in Interface Builder. In the attributes inspector tab leave the standard mode "Class" and class name on "NSMutableDictionary", but switch "Prepares Content" on. In the bindings inspector bind "Content Object" to "Shared User Defaults Controller", controller key "values" and "Model Key Path" to your dictionary's key in User Defaults. Switch "Handles Content As Compound Value" on.
Now you can bind your text field (or check boxes etc). values to the ObjectController, with controller key "selection" (!) and the keys in your dictionary (as model key path).
Hope this helps. I couldn't find the answer in Apple's documentation and also not in the net, was lucky to find it out myself by trying different controller objects...
First: #keeluu's answer should be marked correct.
Doing it Programmatically
If you're doing this in code rather than through IB, there's a "gotcha" to look out for. It looks like this:
// Assume 'anObjectController' is an NSObjectController.
// Assume 'userDefaultsController' is [NSUserDefaultsController sharedUserDefaultsController]
// Assume 'someDictionary' is an NSDictionary in userDefaults.
[self.anObjectController
bind:NSContentBinding
toObject:userDefaultsController
withKeyPath:#"values.someDictionary"
options:#{NSHandlesContentAsCompoundValueBindingOption: #YES}];
If you do the above, you'll find that when you bind your UI elements to properties in someDictionary, those UI elements will correctly display the values that are IN user defaults, but when you change them (by say, clicking a bound checkbox) those values will NOT be updated in user defaults; the old values stick around.
The Reason
The binding must be to NSContentObjectBinding instead of NSContentBinding. The NSObjectController class exposes a binding named contentObject. When you bind to that, everything works properly.
This is an easy mistake to make because Xcode's code completion automatically goes for NSContentBinding and it's one of the most frequently used binding names anyway. This just cost me hours of trouble, so hopefully I saved someone else some time.
Try to add NSDictionaryController to you .xib file, then bind its Controller Content to your dictionary in User Defaults. Then you can bind text field values to Dictionary Controller (arrangedObjects key).
I never tried that but I think it must work.
Hope, it helps.

How do I set TreeController's Content Object when showing a NSXMLDocument in Outline View

I would like to show a NSXMLDocument in Outline View. Thankfully apple has a document for that called "Using Tree Controllers With NSXML Objects".
But one thing I did not get is that how I set TreeController's Content Object.
Firstly I set "Bind to" to the NSXMLDocument I want to show and "Model Key Path" to its rootElement. But that won't work.
I find that I have to set "Bind to" to an object who has the NSXMLDocument as its property and set "Model Key Path" to the NSXMLDocument.rootElement.
So why is that ?
I figured out why my first binding attempt did not succeed. Because with the binding like that my NSXMLDocument was created in IB, then I can't set its content actually. (I do not how I can do that)
With my second binding, I can call NSXMLDocument's initWithData method. So my NSXMLDocument gets its data correctly.
So my question became how can I (or is it possible) to set NSXMLDocument content if it is created with IB ? Because event with awakeFromNib method, I don't know how I can set its content. I tried to call setRootElement, but get's exception said that "Cannot add a child that has a parent; detach or copy first"

Resources