ShaunArchibald
ShaunArchibald

Reputation: 59

Collection View Button Action (Cocoa, Xcode)

In XIB file I have a collection view which contains a button. In awake from Nib i have defined several of buttons with different images. So the application basically looks like a finder, but does not perform any actions yet.

What I want to do now, is that when pressing each button a different file opens (I use filemanager method). I can do this easily in non-collection view type application, but when using collection view I am not sure how to attach different action to each button.

This is what I have, but that would open the same pdf.pdf for every button, when I want every button to open different pdf.

@implementation AppController
-(void) awakeFromNib {


MyButton *Button1 = [[MyButton alloc] init];
Button1.image = [NSImage imageNamed:@"img1"];


MyButton *Button2 = [[MyButton alloc] init];
Button2.image = [NSImage imageNamed:@"img2"];

MyButton *Button3 = [[MyButton alloc] init];
Button3.image = [NSImage imageNamed:@"img3"];

_modelArray = [[NSMutableArray alloc] init];
[controller addObject:Button1];
[controller addObject:Button2];
[controller addObject:Button3];}

- (IBAction)OpenCVFile:(id)sender {


NSFileManager *fileManagerCv = [[NSFileManager alloc] init];
NSString *filePath = @"Users/Tom/pdf.pdf";

if ([fileManagerCv fileExistsAtPath:filePath]) {
    NSLog(@"File exists");
    [[NSWorkspace sharedWorkspace]openFile:filePath withApplication:@"Finder"];}
else {
    NSLog(@"File does not exist");

}
}

Could anyone help? Any help would be appreciated.

Upvotes: 0

Views: 230

Answers (1)

Renfei Song
Renfei Song

Reputation: 2960

Using Bindings

First off, introduce a property to your model class that points back to the controller.

For example, a very simple model class would be:

@interface ModelData : NSObject

@property NSString *name;
@property id controller;

@end

@implementation ModelData
@end

Initialize your collection view's content:

// In the controller
ModelData *data1 = [ModelData new];
data1.name = @"Apple";
data1.controller = self;

ModelData *data2 = [ModelData new];
data2.name = @"Boy";
data2.controller = self;

[self.collectionView setContent:@[data1, data2]];

In interface builder, select the button in your prototype Collection View Item, navigate to the Bindings Inspector, create bindings for Argument and Target:

  • For Argument, set Bind to to Collection View Item, then set the Model Key Path to any property in your model class that you can use to uniquely identify the button (e.g. representedObject.name), and set the Selector Name to your action method's signature, say buttonClicked:.

  • For Target, set Bind to to Collection View Item, then set the Model Key Path to something that points to your controller class (where the action method is implemented), and set the Selector Name the same as above.

enter image description here enter image description here

After these two bindings are set up, your action method in the controller class will be called with the argument you designated when the button is clicked.

// In the controller
- (IBAction)buttonClicked:(id)anArg {
    NSLog(@"%@", anArg);
}

Upvotes: 1

Related Questions