NSCollectionView draws nothing
Asked Answered
I

1

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

Infrasonic answered 21/10, 2009 at 0:25 Comment(5)
How do you modify the mutable array in the delegate? Can you post the code?Suprasegmental
I have edited the post and added the code I useInfrasonic
The code you posted doesn't tell us anything about whether your bindings are connected properly. You'll need to post the project somewhere.Huerta
Edited post and added the link to the projectInfrasonic
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 issueInfrasonic
D
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];
Direct answered 3/11, 2009 at 6:34 Comment(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.Haematoxylin

© 2022 - 2024 — McMap. All rights reserved.