NSArrayController "Content set" bound to NSTreeController issue - cocoa

I have an NSOutlineView bound to a NSTreeController and a CoreData Datamodel.
NSOutlineView displays his data properly.
A NSTableView's cell values bound to a NSArrayController, displaying data from CoreData.
NSTableview displays his data properly too.
The Datamodel has a relationship between data for NSOutlineView and NSTableView
When I try to bind NSArrayController's "Content set" to NSTreeController.selection.name
to display all items related to the NSOutlineView selection I get this error:
Cannot create NSSet from object Untitled of class NSCFString
(Where "Untitled" is the value of NSOutlineViews node)
And no data in NSTableView is displayed.
Everything setup in IB - does anyone has a hint for me to get this working?
Thanks a lot!

You want to bind the NSArrayController's Content Set to NSTreeController, it's Controller Key to "selection" and then the Model Key Path should be the relationship name, which I would hope isn't "name". Then in the TableView you bind the column(s)'s value to the NSArrayController, with Controller Key being "arrangedObjects" and Model Key Path the property "name"

Related

Cocoa binding NSTableView within NSTableView

I'm trying to display a NSTableView inside a NSTableView. This is for an iTunes-like albums/tracks view. So there's a list of 10 albums, each album has some tracks. I want to display the albums in the outer table view and the tracks for each album in the inner.
The first NSTableView is bound to an NSArrayController. Each object in the array has its own "tracks" NSArrayController, but I can't figure out how to tell the 'tracks' NSTableView that its content comes from a property of the 'album' NSTableView.
If I understand you right, the source content of the nested array controller comes from objectValue of the owner table cell. So you can't put the array controller content source to be the objectValue of the table cell. I'm doing similar in that I want to filter the array content based on the object value
What I'm doing, which seems to be working, is to make a seperate nib file for your nested table cell view, with it's own nstablecellview subclass. Include the array controller in the nib and create an outlet to it in your cell view subclass.
Register it with the table view in the viewDidLoad method of the tables view controller:
NSNib *cellView = [[NSNib alloc] initWithNibNamed:#"MyTableCellView" bundle:nil];
[myTableView registerNib:cellView forIdentifier:#"myTableCellView"];
Then, in the awakeFromNib method of your cell view subclass, manually make your bindings that require the object value:
[self.arrayController bind:#"contentSet"
toObject:self
withKeyPath:#"objectValue.tracks"
options:nil];
Voila.
Note that when using this technique, the files Owner of the nib file is not your nstablecellview subclass, it is the view controller of the table view.
The problem lies in not understanding the MVC-pattern (Model-View-Controller). Content for a view never comes from another view, it comes from model objects via a controller. The content of each of your tableviews always comes from an NSObjectController, or a subclass like NSArrayController. Basically, there are two solution:
bind the 'tracks' tableview to the selection of the 'album' array controller
create a 'tracks' array controller and bind it to the selection of the 'album' array controller. Bind the 'tracks' tableview to the 'tracks' array controller
A third solution is to use an NSTreeController with an NSOutlineView but outline views and tree controllers are notoriously hard to work with.

CoreData Binding and custom Cell

I have an app with a CoreData Database and a NSTableView.
I want to do a customCell with 3 key values from database.
So I create an NSTextFieldCell Class but the binding is only for a key value.
How I can programmatically bind a NSTableColumn with multiple key value ?
Thanks.
Here's one way to do it which foregoes the need to create a custom cell:
1) In IB, drag over an Array Controller to your Objects sidebar. Under the Attributes Inspector, set its "Mode" to Entity Mode, fill in the "Entity Name" with the name of your entity, and check "Prepares Content". Under the Bindings Inspector, set its "Managed Object Context" to managedObjectContext.
2) In IB, convert your table to be view-based. Select the "Table View" and under the Attributes Inspector, select Content Mode: View Based and change number of columns to 1.
3) In IB, select the "Table Column" and bind its Value to the Array Controller representing your object. Controller Key should be "arrangedObjects" and leave the "Model Key Path" blank.
4) In IB, select the text field (Label) in your NSTableView cell. Bind its Value to the Table Cell View. The "Controller Key" can remain blank and set the "Model Key Path" to objectValue.whateverAttributeName
There's an awesome summary and tutorial of view-based tables at Gentle Bytes.
Tim Isted created a wonderful tutorial on how to programmatically create bindings, if that's specifically what you desire at Blog # Tim Isted.

NSTable CoreData and selection

I have a very simple App. It is a non-document based CoreData app. The nib contains one NSArrayController and a window with a NSTable with one column. Below the table are three buttons, Add, Delete, and Fetch. Below the buttons I have one NSTextField and a fourth button labeled Save.
My model has two Entities, Department an Employee. The Department has one attribute, name. I'm not currently using Employee.
In the AppDelegate.h I have added this code:
#interface HMGAppDelegate : NSObject <NSApplicationDelegate>
{
NSArrayController *_departments;
}
#property (retain) IBOutlet NSArrayController *departments;
and in the AppDelegate.m
- (void) awakeFromNib
{
[[self departments] fetch:nil];
}
The buttons are bound to add: remove: and fetch: on the NSArrayController.
The save button is bound to save: on the AppDelegate
The NSTextField is bound to the instance of the NSArrayController in the nib, ControllerKey is selection, Model Key Path is: name
When I run the app, I can create new entities and change the value of the entities. That all works fine.
What doesn't work is selection in the table. Changing the selected row in the table does not cause the value from that row to be selected in the NSArrayController. I understand I could put a delegate on the table catch SelectionDidChange and explicitly set the selection on the ArrayController, but I wonder if there is an easier way to do this.
I have seen other examples where there are two table views, representing a one to many relationship. Selection in the first table causes the second table to display the dependent entities. (for example choosing a department shows the employees of that department). In the example I'm looking at there doesn't seem to be a NSTableDelegate.
What am I missing? How does the NSTableView communicate its selection back to the NSArrayController?
How did you setup the Binding? If you bind NSTableView's content to NSArrayController, you have to bind the selection & sortDescriptions as well.
As an alternative, you can bind the table column's Value Binding to Array Controller.arrangedObjects and the selection should work.

How to bind the selection of the NSTableView to the NSArrayController

I just want to be able to use the the methods of the nsarraycontroller called remove: and add:
Select the NSTableView. If the inspector window's title shows Scroll View, you need to click the table view again to select it.
In the bindings tab, connect the Selection Indexes binding to the Array Controller's selectionIndexes controller key. This is similar to binding the content to the array controller, except that you don't use the arrangedObjects key.

Populating an NSPopUpButtonCell with string values

I am trying to populate a NSPopUpButtonCell with a list of strings. In -(init), I populate an NSArray with the values I want in the PopUp Button. How do I connect this to the NSArrayController I added in IB? Does my app delegate need an IBOutlet NSArrayController to connect to or is there a way to bind it?
Also, when I bind the NSArrayController to the NSPopUpButtonCell, do which Content do I bind it to? Content or Content Values?
jorj
Bind the array controller's Content Array to your controller's array of strings. Bind both the pop-up button cell's Content and Content Values to your array controller's arrangedObjects.
Presumably, you also want to know which of these strings is selected. To do that, bind the pop-up button cell's Selected Object (which will be one of the objects in Content) to a property of your controller (the one that owns the original array).

Resources