I'm developping a little DB book management Mac OSX app with CoreData and DataBindings.
I have a TableView with all the book authors.
I would another TableView that rapresent all books written by the author selected in the previous table...
The both tables are managed with two ArrayController in IB.
My problem is that I don't know how to filter the second table / ArrayController with the first table selection.
I must also insert a new book in the filtered ArrayController.
I can do it?
Thanks a lot!
I actually wrote a tutorial that might be of help http://themikeswan.wordpress.com/2009/05/22/7/ the short answer is that you bind the array controller for the book table to get it's Content Set from the selection of the other array controller. The book array controller would then get it's items from whichever author is selected in the author array controller. You should also just have to add a button for adding books and connect it to the book array controller's add: method (I have not tried this as of yet, but in theory it should work, I'm not sure if the author relationship will get properly set though).
You should read about NSPredicate, array controllers supports them for filtering the content. To add a new book you should override "add:" method of the ArrayController (subclass it) or write a custom method somewhere in the window controller that will construct new object and push it into the ArrayController with addObject: call.
Related
Every tutorial I read about data binding / NSArrayController told to set the Mode and the Keys in the Object Controller (Attributes Inspector) for the data model class I use. Why do I have to do this?
In my sample application I create all objects in code and add them to the array controller in code too. The program still works fine without any settings in the Object Controller. I use the NSCollectionView to present my data.
To answer the question in the subject, the Object Controller section lets you determine what the array controller is controlling. In your screenshot the array controller is controlling objects of a Person class. But the array controller can also control a Core Data entity. That's what the Mode menu is for. The keys are pieces of the object/entity the array controller is controlling.
The reason the tutorials tell you to set the mode and keys is they are demonstrating using NSArrayController with Cocoa bindings. You must set the mode and keys so you can bind the array controller to the collection view in Interface Builder and have the collection view display relevant data from the array controller. If you are writing code to do all the NSArrayController work and not using Cocoa bindings, you can avoid setting the mode and keys.
I'm attempting to use Cocoa bindings to populate an NSTableView using Core Data entities. I've arrived at a point where I'm boggled by the behavior of my application. The array controller is in "Entity Name" mode and is using the my "Song" entity.
The table view I am attempting to load the data into has two columns: one for the song name and another for the artist name (the artist is another entity which has a relationship to a song). Through Interface Builder, I have been able to successfully bind the array controller to the table, and setup bindings for the two columns. However, for some reason, one of the columns' bindings is working perfectly (artist name) while the other is not populating at all (song name).
I have gone through each view in the Document Outline and ensured that both columns are configured in exactly the same manner. I've attached some screenshots below showing the binding setup in Interface Builder.
Binding on the NSTableColumn representing the Song Title
Binding on the NSTextField within the NSTableCellView (the one that is not working)
Binding on the NSTextField for Artist Name (the one that is working)
The final (non-functioning) result
Is there an obvious reason why this approach is not working? Any help would be greatly appreciated. I can also provide any additional information that may be needed to answer this question.
It appears you are using a "view" based NSTableView as opposed to the older "cell" based. Each have a different configuration for bindings. In a view based table view you have to bind the tableview content to the array controllers arrangedObjects (see below), you don't have to deal with the individual column bindings that is for cell based table views.
Your remaining bindings look fine.
Just a wild guess. Since you're speaking of the Song entity.
Can it be that you have to bind the song name to objectValue.song.title?
If 'Artist' isn't just an attribute of the 'Song' entity but an entity itself (which it must likely be if it has a relationship to 'Song') then I think you need to have a separate array controller connected to that column in order for it to work properly.
I'm learning Core Data and at the moment just using Interface Builder and the XCode data model (following the Aaron Hillegass Cocoa book examples).
I have an MVC application and core data set up and working within interface builder (no hand-written code yet). I've set up various arraycontrollers, views and buttons to add and remove objects and edit data and determine relationships between objects.
However my object model is strictly hierarchical parent-child (and grandchildren) and each relationship is one-to-many. So when I add a child (or grandchild) I want to automatically assign the parent object currently selected in the main tableView as the parent of the new child object.
Is this possible in interface builder or is this the point where I have to start coding my own methods?
Any pointers on the next step I should be looking to take or how to figure it out myself much appreciated. I'm just a bit stuck and can't find a relevant tutorial or reference.
Perhaps it will help if I describe my document window. It has two tableViews with add/remove buttons. The tableView on the right displays an NSSet of the child objects of the parent objected selected in the tableView on left. I want the add button on the right to add a new object and automatically make it a child of the selected parent object so it appears in the tableView on the right.
At the moment the only methods I can see on the arrayController for the the child objects are add: and remove: but of course they don't connect the new object to the currently selected parent. Do I need to add my own (IBAction) method to the parent object i.e. addChildObject:? Or is there a built in way to add the child automatically within CoreData based on the parent-child relationship?
Problem solved. I found a tutorial (albeit a bit dated) describing exactly what I am trying to do:
https://developer.apple.com/cocoa/coredatatutorial/index.html
And after studiously following every step carefully I realised I had done everything right I had just missed one binding: I had only set the Content Set of the child array controller and not its Managed Object Context (to File's Owner). That is the only reason my add button was not adding a new child object! Trivial mistake, but when you are not confident you question you're whole approach rather than looking for a simple error. Sorry for anyone who had to read this but maybe the link to the tutorial will help someone.
This is the scenario: A Core Data model with an entity which contains a relationship to a second entity. The latter entity contains an attribute which is an image and a second attribute with is a name (NSString).
The GUI is a NSTableView which is bound to a NSArrayController. One column of the table is a NSPopUpButtonCell. It is setup so that it currently contains the names of the second entity. It works well so far.
The problem is that I would like to show the image instead of the name. NSPopUpButtonCell is basically able to show images but I'm not able to setup the proper bindings. Setting the bindings directly in the cell doesn't work and the column binding of the table view doesn't feature an image as binding.
It's a little bit complicated but maybe someone can gibe me a hint!
Thanks in advance,
Thomas
I'm working on a application with the this interface (sorry the language is Dutch):
http://www.flickr.com/photos/pluueer/5756159100/
The Add function (incl. the four NSTextFields) under the NSTableView are to moved to a sheet someday, but for now this is fine. I've set up bindings according to a tutorial (http://cocoadevcentral.com/articles/000080.php), but the tutorial doesn't supply how to add rows in the way I want to (just adds an empty row which you need to edit in the NSTableView).
I've got a connection between the 'Voeg toe' (Dutch for 'Add') button and the Array Controller. But after clicking I get the message:
2011-05-28 23:37:56.149 Hop Calc[4345:a0f] -[__NSPlaceholderDictionary initWithObjects:forKeys:]: number of objects (0) not equal to number of keys (4)
It makes sense, because I've not implemented anything for adding rows, but I just don't know how.
"Add a row to the table" is the wrong way to think of it. Your table represents a collection and a controller provides the information to the table, mediating between the table (view) and the collection (model). Since you mentioned bindings, the collection is likely managed by an NSArrayController. So you want to add a new object (of the kind your array controller manages) to the array controller's content array.
Simplest way: Connect the Add button to the -add: action of the NSArrayController. It'll add an empty row.
If you want more control, connect the Add button to your own custom action in some controller. That action will create an instance of whatever's represented by your array controller, prepopulate it (or whatever you want to do), then, using an outlet it holds to your NSArrayController, will call the array controller's -addObject: method to add the object (the possibly a -rearrangeObjects call to get the array controller to re-sort its contents).