7

I'm trying to set up an NSCollectionView (I have done this successfully in the past, but for some reason it fails this time).

I have a model class called "TestModel", and it has an NSString property that just returns a string (just for testing purposes right now). I then have an NSMutableArray property declaration in my main app delegate class, and to this array I add instances of the TestModel object.

I then have an Array Controller that has its Content Array bound the app delegate's NSMutableArray. I can confirm that everything up to here is working fine; NSLogging:

[[[arrayController arrangedObjects] objectAtIndex:0] teststring]

worked fine.

I then have all the appropriate bindings for the collection view set up, (itemPrototype and content), and for the Collection View Item (view). I then have a text field in the collection item view that is bound to Collection View Item.representedObject.teststring. However NOTHING displays in the collection view when I start the app, just a blank white screen. What am I missing?

UPDATE: Here is the code I use (requested by wil shipley):

// App delegate class

@interface AppController : NSObject {

NSMutableArray *objectArray;
}
@property (readwrite, retain) NSMutableArray *objectArray;
@end

@implementation AppController
@synthesize objectArray;

- (id)init
{
    if (self = [super init]) {
    objectArray = [[NSMutableArray alloc] init];
    }
    return self;
}


- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    TestModel *test = [[[TestModel alloc] initWithString:@"somerandomstring"] autorelease];
    if (test) [objectArray addObject:test];
}
@end

// The model class (TestModel)

@interface TestModel : NSObject {
NSString *teststring;
}
@property (readwrite, retain) NSString *teststring;
- (id)initWithString:(NSString*)customString;
@end

@implementation TestModel
@synthesize teststring;

- (id)initWithString:(NSString*)customString
{
    [self setTeststring:customString];
}

- (void)dealloc
{
    [teststring release];
}
@end

And then like I said the content array of the Array Controller is bound to this "objectArray", and the Content of the NSCollectionView is bound to Array Controller.arrangedObjects. I can verify that the Array Controller has the objects in it by NSLogging [arrayController arrangedObjects], and it returns the correct object. Its just that nothing displays in the NSCollectionView.

UPDATE 2: If I log [collectionView content] I get nothing:

2009-10-21 08:02:42.385 CollViewTest[743:a0f] (
)

The problem is probably there.

UPDATE 3: As requested here is the Xcode project:

http://www.mediafire.com/?mjgdzgjjfzw

Its a menubar app, so it has no window. When you build and run the app you'll see a menubar item that says "test", this opens the view that contains the NSCollectionView.

Thanks

Peter Hosey
  • 95,783
  • 15
  • 211
  • 370
indragie
  • 18,002
  • 16
  • 95
  • 164
  • How do you modify the mutable array in the delegate? Can you post the code? – Wil Shipley Oct 21 '09 at 11:02
  • I have edited the post and added the code I use – indragie Oct 21 '09 at 14:01
  • The code you posted doesn't tell us anything about whether your bindings are connected properly. You'll need to post the project somewhere. – NSResponder Oct 21 '09 at 21:21
  • Edited post and added the link to the project – indragie Oct 21 '09 at 22:36
  • 2
    I seem to have found the problem, and it is a very strange issue. I tried adding my TestModel object directly to the array controller, instead of the NSMutableArray which is bound to the controller, and suddenly it starts working. And I see that the object which I have added to the array controller is also now present in the NSMutableArray, which rules out bindings as an issue. How is it that when I directly add it to the array controller it works, and otherwise it doesn't? I've used NSCollectionView before an havent run into this issue – indragie Oct 22 '09 at 01:01

1 Answers1

4

The problem is that your not correctly using KVC. There is two things you can do.

Method 1: Simple but not so elegant

  1. Use the following code to add the object to the array

[[self mutableArrayValueForKey:@"objectArray"] addObject:test];

This isn't so elegant as you have to specify the variable using a string value, so you will not get compiler warnings when spelt incorrectly.

Method 2: Generate the KVO methods needed for the array "objectArray".

  1. Select the property in your interface declaration
  2. Select Scripts (the script icon in the menubar) > Code > Place accessor decls on Clipboard
  3. Paste the declarations in the appropriate spot in your interface file
  4. Select Scripts > Code > Place accessor defs on Clipboard
  5. Paste the definitions in the appropriate spot in your implementation file

You can then use a method that looks like

[self insertObject:test inObjectArrayAtIndex:0];
Chetan
  • 46,743
  • 31
  • 106
  • 145
Brad G
  • 2,528
  • 1
  • 22
  • 23
  • 1
    If you are worried about passing string values (as you should be), you could create a static NSString in your class : `static NSString *objectArrayKey = @"objectArray";` and then you can call `[[self mutableArrayValueForKey:objectArrayKey] addObject:test];` which gives you all the compiler support and autocompletion. – Abizern Nov 05 '09 at 11:23