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).
Related
Is there a simple way to bind a NSMutableArray made up of Strings to a Single column NSTableView without creating any new classes?
Make an NSArrayController in interface builder. Bind its Content Array to your mutable array, like so:
Then bind your table column to that array controller, like so:
(Note the self in the model key path field. That's what makes it work with an array of strings.)
Assuming you're using a view-based NSTableView, you must bind the entire table view (not the column) to the array controller's arrangedObjects. Then, bind the text field's value to the containing cell view's objectValue property.
This is documented here.
For cell-based NSTableViews, Amy Worrall's answer is the correct approach.
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".
I'm exploring bindings right now, and have an NSPopUpButton -
It presents me a number of options for bindings under Value Selection - Content, Content Objects, Content Values, and then Selected Object, Selected Value, and Selected Tag. Could someone please explain the difference between these?
Those are explained in the Cocoa Bindings Reference for NSPopUpButton, although that reference is not quite clear.
Content is an array controller that provides elements to the popup button. The array controller should be bound to an array. In order to determine how each element in the array is shown in the popup button, -description is sent to each object in the array.
You may customise this in two ways:
If you want the Selected Object binding to provide an object distinct from the array elements managed by the array controller to which Content was bound, you can bind Content Objects to another array controller. It could also be the same array controller but with a different key path;
If you want the popup button options to be something different than the description of each element in the array managed by the array controller to which Content was bound, you can bind Content Values to another array controller that manages an array whose elements contain the popup options. It could also be the same array controller but with a different key path.
A simple example: suppose you have the following class:
#interface Customer : NSObject
#property (copy) NSString *name;
#property (copy) NSString *phoneNumber;
#end
and you haven’t overridden the -description method. In this case, -descriptionis useless and the name property would be a good choice for the popup options. You’d bind:
Content to an array controller that manages an array of Customer instances, controller key arrangedObjects;
Content Values to the same array controller, controller key arrangedObjects, model keypath name.
You can then bind Selected Object to something else, for example a property in your application delegate or window controller. Cocoa bindings would then assign the selected Customer instance to that property.
Now suppose you are not interested in the whole Customer object that’s been selected, but only its phone number. In this case, you can bind Content Objects to the same array controller, controller key arrangedObjects, model keypath phoneNumber. When a popup option is selected, Cocoa bindings will set phoneNumber instead of an entire Customer instance. In summary: if you don’t bind Content Objects, Selected Object represents the original object in the array. If you bind Content Objects, then Selected Object can be something different.
You’d bind Selected Value if you were not interested in the original objects (or the content objects), but the actual strings shown in the popup options according to the Content Values bindings.
Quick recipe for providing data to the popup button:
Bind Content if you have objects (not only strings) that represent the popup options;
Bind Content Values if the options that are shown to the user cannot be obtained via Content by sending -description to the array elements;
Bind Content Objects if you want Selected Object to return something different from the array elements from Content.
Quick recipe for obtaining the current selection in a popup button:
Bind Selected Object if you want to know the full object (either from Content or Content Objects) representing the current popup selection;
Bind Selected Value if you only want the string that’s currently selected in the popup.
And lastly, you’d use Selected Tag if the popup options are actually taken from a menu whose items have a tag set.
#Object refers to any KVC-compliant object. #ObjectValue refers to the key path used to get the value from that object.
So, for your pop-up binding, ContentObjects would be bound to, say, an NSArrayController's arrangedObjects. Say this refers to an array of dictionaries or managed objects. You can't meaningfully present a dictionary in a pop-up (you get the start of the description output, e.g <NSCFDictionary... or similar), so this is where the contentValues binding comes in. This would be something like your NSArrayController's arrangedObjects.name, where name is a key from your dictionary or managed object.
I hope this helps, I struggled with the same concept myself when I started with bindings.
I have an application with a view that have a tableView which is populated with strings from an array, and also have a navBar with a plusButton. What I want is that when I press the plusButton I want to be able to add items to that array.
Add action method (IBAction) to that UIButton that is implemented in table view control class.
Implement in that method adding new object to your array
Reload table view (or call appropriate methods to add row one by one) after modifying array
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.