Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle a button click from NSCollectionView

I have a NSCollectionView (OS X, not iOS) bound to my model. Each collection view item has a button and a label. I'm handling the click actions and I have the sender and event arguments but I unable to distinguish one button from the others. Most other questions not dealing with Collection Views say to use the tag property, but this isn't exposed on the Interface Builder's bindings tab. There is an Argument and Argument2 bindings, but they dont seems to correspond to the tag property in the objc code and I don't know how to otherwise access these Arguments.

-(void)image_click:(id)sender forEvent:(NSEvent *)event
{
    NSButton *btn = sender;
    NSLog(@"image clicked, %ld", (long)btn.tag);   //image clicked, 0
}

How do I differentiate between buttons in Objective-C code inside the click actions of a bunch of buttons in a collection view?

like image 964
Jeff Avatar asked Jun 26 '13 17:06

Jeff


3 Answers

I'm assuming you want to determine the model object being represented by the button in the view. I was able to determine the model object by looping over the buttons in the collection view. I couldn't use the selection index or any other similar attribute, but in the end, the model can be determined.

Assuming your NSArrayController already has your array, then do the following:

Bindings:

The Collection View only needs one binding

Bind to:         <NSArrayController instance>
Controller Key:  arrangedObjects
Model Key Path:  <blank>

Controller:

You should hook up the controller to the content view

property (weak) IBOutlet NSCollectionView *collectionView;

Finally, the controller receiving the button click message should implement this IBAction:

- (IBAction) collectionViewClick:(id)sender
{  
  id objectInClickedView = nil;

  for( int i = 0; i < [[self.collectionView content] count]; i++ ) {
    NSCollectionViewItem *viewItem = [self.collectionView itemAtIndex:i];

    if( [sender isDescendantOf:[viewItem view]] ) {
      objectInClickedView = [[self.collectionView content] objectAtIndex:i];
    }
  }
}

Which will assign the object to objectInClickedView. If you're actually interested on the view or viewItem, you can modify the code.

like image 109
Dave FN Avatar answered Nov 15 '22 08:11

Dave FN


Add a Model in your project named MyModel and declare property uniqueID in MyModel.h

@interface MyModel:NSObject  
@property (retain) NSString* unqiueID;  
@end  

MyModel.m

@implementation MyModel  
@synthesize uniqueID=_uniqueID;
@end

In AppDelegate.m create some model objects and add them into an array

In IB add an ArrayController and bind it to the array declare in AppDelegate

In IB select CollectionView and bind its Content property to ArrayController and set its ControllerKey property to arrangedObjects

In your Template View Use NSButton's Target and Argument bindings to send unique arguments to the selector specified

Your Arguments binding should look like this
Bind to: Controller View Item
Model Key Path: representedObject.uniqueID
Selector Name: buttonClicked:

and Target bindings
Bind to: App Delegate
Model Key Path: self
Selector Name: buttonClicked:

The steps are explained in detail in the following tutorial
https://developer.apple.com/library/mac/documentation/cocoa/Conceptual/CollectionViews/Introduction/Introduction.html#//apple_ref/doc/uid/TP40009030
Hope this helps

like image 38
Nisar Ahmed Avatar answered Nov 15 '22 09:11

Nisar Ahmed


I would do it like this (because the button you want to press should be coupled with the corresponding model, therefore the represented object):

  1. Add a method to the model of your collectionViewItem (e.g. buttonClicked)
  2. Bind the Button Target to Collection View Item
  3. While binding set model key path to: representedObject
  4. While binding set selectorname to: methodname you chose earlier (e.g. buttonClicked)
  5. Add protocol to your model, if you must tell delegate
like image 27
Dom Avatar answered Nov 15 '22 08:11

Dom