NSCollectionView get selected item on button click - cocoa

I have a NSCollectionView is bound to an NSArrayController that has an NSMutableArray as content. Items in the NSMutableArray are displayed as they should.
I have an WindowController class that holds a reference to the NSMutableArray. There is also a button that causes a buttonClicked message to be sent to my WindowController.
Now inside buttonClicked I want to know what item is selected in the NSCollectionView. How do I do this? I have no reference to the NSArrayController otherwise I could have asked it by sending selection. I've studied some sample code but to no avail.
How can I get a reference to the currently selected item in the NSArrayController?

if the NSCollectionView is getting its content from the NSArrayController, as there is a binding set in IB on content or you have programmatically bound these, there is also a binding available on the collectionView's selectionIndexes, which when bound to the arrayController will give you 'a reference to the currently selected item' in the arrayController and the collectionView.
NSCollectionView's itemAtIndex, handed the currently selected item's index, will get you the actual item that is selected.
is the actual item that is selected what you are looking to obtain a reference to?

Related

NSPopupButton not updating when using setValue:forKey: against it's CoreData bound field

I'm working on a CoreData / Document based app. In one area of the UI I've setup a view-mode table with various columns. One column has an NSPopupButton in it with the Selected Index binding setup as Table Cell View.objectValue.startupState.
Picking any of the menu items in the popup will correctly update the startupState attribute on the entity with the index of the menu item clicked and the NSPopupButton text updates as well. I've verified the attribute value is in fact updated by saving, closing, and re-opening the document.
In another column I have an NSPopupButton bound similarly to another attribute in the same entity - Table Cell View.objectValue.mode. Depending on the mode selection it will modify the startupState value through a manual implementation of setMode which does this statement in certain cases:
[self setValue:[[NSNumber alloc] initWithInt:1] forKey:#"startupState"];
The issue I'm having is that the NSPopupButton isn't updating to show the menu item text for the selected index. As before, I saved, closed, and re-opened the document after the above code ran and the correct item was selected / text appeared so I know the setValue call updated the attribute.
Any ideas?
As mentioned in the comments, Volker's suggestion addresses the issue. willChangeValueForKey and didChangeValueForKey messages are needed around the setValue:forKey call like this:
[self willChangeValueForKey:#"startupState"];
[self setValue:[[NSNumber alloc] initWithInt:1] forKey:#"startupState"];
[self didChangeValueForKey:#"startupState"];

Can I set a property when created with bindings?

I'm trying to build a To-do list application. I have 2 tablesviews and one textfield. In the first tableview are the different projects, and when you click on one of them the associated todos appear in the second tableview. It's a pretty basic Master-detail I guess.
I set it all up with bindings.
Right now the way you add a task, is you click on an add button and it adds a row with a placeholder text that's editable.
But what I want, is the user to enter the task in the textfield, press add, and then it adds the todo with the name already set.
So basically I have TodoItem Class with a name property, and my question would be, how do I get the content of the nstextfield and assign it to the name property ?
I tried creating an outlet from the Todoitem class to the textfield, but xcode won't let me connect it....
Tell me if you need to see any code, but since I used bindings, there's almost nothing to show. Thanks!
… how do I get the content of the nstextfield and assign it to the name property ?
Translate that directly into Objective-C:
NSString *contentOfTheNSTextField = [myTextField stringValue];
myNewTask.name = contentOfTheNSTextField;
You'd do that in the action method that you've set both the button and the field to call.
I tried creating an outlet from the Todoitem class to the textfield, but xcode won't let me connect it....
To do this, the Todoitem would need to reside in the nib.
But, even if you could do that, why should the model object know about the text field? Carrying values between model and view is a controller's job.

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

How to add multiple menu items with the same title to NSPopUpButton(NSMenu)?

As docs say it's impossible to add two menu items to NSPopUpButton if they both have the same title. I was trying to add menu items to [popupButton menu], but with no luck. I was also trying to create a new menu, add items to it and then use [popupButton setMenu:newMenu], but no. Menu always display only one item per name.
But I know it should be possible, if you try to create a smart playlist in iTunes, you could select "Playlist" from the left popup button, "=" from the middle, and the right one will hold menu items for every playlist in iTunes EVEN if they have the same title. So how do they do it?
While NSPopUpButton methods like addItemWithTitle: and addMenu: won't allow duplicate names, it is definitely possible to have items with the same title. You simply have to set the name on the NSMenuItem itself.
For example, if you have an array of strings (like playlist names perhaps) you want to add them to a popup button, and want to make sure duplicates will be in there, do it like this:
NSArray* items = [NSArray arrayWithObjects:#"Foo", #"Bar", #"Baz", #"Foo", nil];
for (NSString* item in items)
{
[popupButton addItemWithTitle:#"blah"];
[[popupButton lastItem] setTitle:item];
[[popupButton lastItem] setTarget:self];
[[popupButton lastItem] setAction:#selector(something:)];
}
Instead of using addItemWithTitle:, you can create an NSMenuItem manually and add it directly to the menu. This allows you to specify any title you want, as well as being able to insert it at any location in the menu.
NSMenuItem* newItem = [[NSMenuItem alloc] initWithTitle:#"foo" action:#selector(something:) keyEquivalent:#""];
[newItem setTarget:self];
[[popupButton menu] addItem:newItem];
[newItem release];
I had the exact problem and it was solved easily. Instead of using NSPopUpButton methods such as –addItemWithTitle: to manipulate the button items, I added an NSArrayController and added the items into the array controller instead. Then I used the bindings to bind the controller and the popup button and now it shows items with same titles.
To do the bindings:
Add an NSArrayController in IB.
Set the NSPopUpButton bindings for "Content" to Array Controller with the "Controller Key" being "arrangedObjects"
Set the NSPopUpButton bindings for "Selected Index" to Array Controller with the "Controller Key" being "selectionIndex"
[Optional] Select the array controller and set the Class Name in attributes to whatever class your items are e.g. NSString or you can use the default NSMutableDictionary and add keys in the box below which consequently lets you wrap your items in a dictionary and add different keys for what you want to show in popup button and what you want to have in background. To set which key of the dictionary you want to be reflected in the popup button, go to popup button's bindings for "Content" again and set the "Modal key Path" to the key you added in the array controller attribute.
Swift 5
Add using guaranteed unique title, then alter title in next statement.
"accountPU" is NSPopUpButton object
"from" is an account object.
accountPU.addItem(withTitle: "\(from.accountID!)")
accountPU.lastItem!.title = from.name

Resources