Question

I'm kinda new into bindings, somehow prevented it. But I want to use them now. Talking about OSX and this is programmed in code not in IB.

So, I have data coming from CoreData into my ArrayController. A NSCollectionView is bound to this arraycontroller and if there is data, this binding works the data is displayed.

But, each item has some buttons, sliders, textfields. On a click, a code will change the tag or value of those things. I thought it is enough when I send the change to coredata and save it. Shouldnt the arraycontroller get this and update my items in the collectionview?

Because the tags(first thing I tried) dont get updated if its updated in coredata.

Do those fields have to be somehow bound?

the tag is set in a subclass of NSCollectionViewItem this way:

[[(BEItem *)[self view] valueSlider] setTag:[[representedObject itemTag] intValue]];

Is there anything I have to tell the CollectionView to update itself and take the new data from the controller?

Thanks Benjamin

EDIT

I have changed my collectionview. I read it isnt really possible to bind a representable object and in the answer below, it is bound to some property, but this property isnt updated either. Then I read about newItemForRepresentedObject that you should use this function. Now, I created everything like shown below, but the program is always crashing after 10 seconds or something and nothing is displayed. It is continuously calling setChannelID, but never setting the ID to the property. Because of that it is always called I think this is the problem. (The if gets never to only return)

What is the problem here? Im really confused by the collectionview by now. And this is just code, nothing in IB.

Setting up the View in appdelegate:

NSCollectionViewItem *testitem = [[NSCollectionViewItem alloc] init];
[testitem setView:[ChannelView new]];


self.collectionView = [[ChannelCollectionView alloc] initWithFrame:NSMakeRect(10, 0, mixerWidth, self.splitview.frame.size.height)]; // initWithFrame:[[[self window] contentView] frame]

 [self.collectionView setItemPrototype:testitem];
[self.collectionView setMaxNumberOfRows:1];
[self.collectionView setAutoresizingMask:(NSViewMinXMargin | NSViewWidthSizable | NSViewMaxXMargin | NSViewMinYMargin  | NSViewHeightSizable| NSViewMaxYMargin)];
[self.collectionView setAutoresizesSubviews:YES];
[self.collectionView bind:NSContentBinding toObject:self.channelController withKeyPath:@"arrangedObjects" options:nil];

ChannelView:

#import <Cocoa/Cocoa.h>

@interface ChannelView : NSView

@property (readwrite, nonatomic, copy) NSString *channelName;
@property (readwrite, nonatomic, copy) NSNumber *channelID;

@property (readwrite) NSTextField *channelNameField;
@property (readwrite) NSTextField *deviceChannelField;



@end


@implementation ChannelView

- (id)initWithFrame:(NSRect)frame
{
self = [super initWithFrame:NSMakeRect(0, 0, 300, 500)];
if (self) {
    // Initialization code here.

    ColorView *test = [[ColorView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)];

    self.channelNameField = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 100, 20)];
    self.deviceChannelField = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 50, 100, 20)];

    [self addSubview:test];
    [self addSubview:self.channelNameField];
    [self addSubview:self.deviceChannelField];
}

return self;
}

-(id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];


    //add die teile


return self;
}

- (void)drawRect:(NSRect)dirtyRect
{
// Drawing code here.
}


// setters.


 -(void)setChannelID:(NSNumber *)chanID
{
    //NSLog(@"hallo");
if (self.channelID == chanID) {
    return;
    NSLog(@"da");
}
else {
    NSLog(@"hello"); //just this in debug output
self.channelID = [chanID copy];
    NSLog(@"no output");
        // self.channelID = chanID;
NSLog(@"chanid %d current: %d", chanID.intValue, self.channelID.intValue); //never shown in debug
[self.deviceChannelField setStringValue:[NSString     stringWithFormat:@"%d",self.channelID.intValue]];
}
} 

@end

And this piece in my subclasses NSCollectionView

- (NSCollectionViewItem *)newItemForRepresentedObject:(ChannelsToMixes*)object
{
NSCollectionViewItem *item = [super newItemForRepresentedObject:object];
    // ChannelView *view = (ChannelView *)[item view];

NSLog(@"cahnnelid: %d",object.channelID.intValue);

    // [view bind:@"title" toObject:object withKeyPath:@"title" options:nil];

     [item.view bind:@"channelID" toObject:object withKeyPath:@"channelID" options:nil];
    //NSLog(@"test");

    //NSLog(@"%@",object);

return item;
}

If anyone knows why the setter isnt setting the property give me a tip :) It should be able to do this and is not released or anything, at least that I know of (using ARC)

Was it helpful?

Solution

Yes, you have to bind the value of your slider to your CollectionViewItem.

You can either do this in code with this method:

-bind:toObject:withKeyPath:options:

Which would look in your example like this:

[[(BEItem *)[self view] valueSlider] bind:@"tag" toObject:self withKeyPath:@"itemTag" options:nil];

Or, if you use IB, in the InterfaceBuilder by setting the value to bind to your Colletion View Item representedObject.itemTag

enter image description here

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top