NSTableView bindings how to add a row - cocoa

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).

Related

Cocoa bindings issue with three tableviews

im a osx-dev noob that is trying to build an application with three table views that will show the content of a core data store entity. But each table view is filtered on the attribute "status" of the entity.
the problem occurs when i also want to show the selected entity in textfields. I'm using three different array controllers with different fetch predicates. But in a textfield i can only bind the value to one array controller.
should i ditch the bindings and do it all programaticly or is there a simple solution to this? :)
here is an screenshot so you can grasp my app description.
Keep bindings to populate the text fields if it satisfies what you want to do with this GUI. I'd add an NSObjectController to control the one entity those fields represent. If you want the user's changes to those fields persisted, bindings are still awesome.
But I think with three tables that might control what's displayed in the text fields, you're going to need to have some sort of non-binding glue code that determines which of the tables wins. You can probably do everything you want by implementing some of the NSTableViewDelegate protocol.
If the text fields should display the last entity that the user clicked in any of the tables, simply have each table call the same tableViewSelectionDidChange delegate function. All three tables could have the same delegate. You can then call setContent on the NSObjectController from that function.
You could also use similar glue code to prevent more than one selection in any of the three tables, by having the same delegate function deselect everything in the other tables either through the view or the controller. But that's up to you and needs consideration of whether you want multiple selection, etc.

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 to rebind nstableview IN COCOA

I have a NSTableView and a NSArrayController for the NSTableView.
there is only one column in the table,"name"
at first, user open one file, in the arrayController will be #[#{#"name":#"1"},#{#"name":#"2"}]
after sometime, the user opened another file, now the content of array controller should be #[#{#"name":#"x"},#{#"name":#"y"},#{#"name":#"z"}].
how can I bind the new data to the NSTableView,(not add)?
You don't need to do anything if you have the bindings set up right. The content array of the array controller should be bound to an array (the one you show in your post), so when you change, or add to that array, the array controller's arranged objects will automatically change -- this doesn't require any "rebinding".

How to get the stringValue of a Text Field Cell inside a Table View after editing the cell?

I have a standard Table View with the default settings inside my main nib. I use an Array Controller and Bindings for dealing with the data that the table view should show to the users. I already achieved that the "add" button inserts the new row and sets the first column to editing mode so the users can type their text immediately. My problem is i can't detect when the editing is over and i should save the new values. I couldn't find any delegate method and/or any notification for this purpose. I searched the internet and i couldn't find anything useful. I'm not even sure that i'm doing it right, i didn't add any specific thing, i just use the standard double click editing that the table view offers for each cell.
Any help is much appreciated.
Thanks in advance!
If you have everything hooked up with bindings, you shouldn't need to save the data until you exit the program. When the array controller's add: method is called, the new record is added to the controller's arranged objects, and the array holding your data is also updated. So, you only need to save the array when your app closes.
However, if you wish to save the data after every edit, you can detect the end of the editing with the delegate method controlTextDidEndEditing:. You will get a notification after each column is finished editing (make sure to make the class where you implement this method the delegate of the table view).

Setting a default selection for an NSPopupButton?

Is it possible to set a default selection on an NSPopupButton? I have one that allows the user to select the type of server they want to set up, but since an NSPopupButton always shows the first item, they may ignore it if that's the type they want. However, even though that item is being displayed, calling -selectedItem returns (null). Everything works fine if the user picks an item from the menu first.
The Button's content and contentValues are bound to the same Array Controller, which in turn is bound to the keys property of an NSDictionary. I've tried binding the selectedIndex to a variable in the controller and updating that in code, but it has no effect. (I may just be binding it wrong...) How can I select the first item by default?
Thanks in advance!
SphereCat1
When using Bindings, you don't need to and shouldn't get any model info—neither the model itself nor selection state—from the views directly. Talk to the controller that owns the model and the selected indexes.
Note that “index” doesn't have any meaning for an NSDictionary, and keys is not a property of an NSDictionary. (Indeed, I would not be surprised if you were to get an exception because your dictionary does not have an object for the key “keys” in it.) It is a method, and not the accessor kind, so while you can ask the dictionary for the value of that method using Key-Value Coding, you should not.
What you should do is make model objects representing the server types, and hold an array of those, and bind the array controller's content to the property whose value is that array. Bind the pop-up button's contentValues to a name property of your model objects, which should hold the localized name of each server type.

Resources