简体   繁体   中英

Problem with NSCollectionView

I'm quite a rookie when it comes to Cocoa programming, so I hope some experts can hint me on the right direction with a problem I'm facing.

I have a NSCollectionView that is bound to a NSArrayController (A) of elements having two properties: an URL to a picture and a NSArray (B) of elements of another class. For every element inside the NSArrayController (A), I load a subview with a NSImageView that should display the image in the URL and a NSTableView that is bound to the elements of the NSArray (B).

Everything works fine, except for one very important thing: the URL to the picture is not immediately available when I create the subview, it becomes available later, but when it does, I don't see the picture loading in the NSImageView. I would think of a problem in the KVC/KVO implementation, but the strange thing is that the image loads correctly if, when the URL becomes available, the subview is not visible (eg in a portion of the scrollview that is not displayed).

Example: The NSScrollview size is such that it can display only two subviews at a time. I add three elements to the NSArrayController (A): the first two images don't load, if I scroll down the scrollview to see the third element, I find the image loaded correctly.

Any ideas about what could cause such a strange behaviour? Thank you in advance

Luca

series.h

@interface Series : NSObject {
@private
NSMutableString * banner;
}
-(Series*)initWithEpisode:(Episode*)ep;
-(void)setBanner:(NSString*)_banner;
@property (retain, readwrite) NSMutableString *banner;
@end

series.m

@implementation Series
@synthesize banner;
-(Series*)initWithEpisode:(Episode*)ep
{
self = [super init];
if(self){
banner = [[NSMutableString alloc]initWithString:@"some invalid URL"];
}
-(void) setBanner:(NSString*)_banner
{
[banner setString:[NSString stringWithFormat:@"some root path/%@", _banner];
}
-(void)dealloc
{
[super dealloc];
[banner release];
}

SeriesListViewController.m

-(void)VideoChangedStatus:(Episode*)ep{
//This is the delegate called by the object Episode when it retrieves the URL via asynchronous call to a webservice
Series *tmp = [[Series alloc]initWithEpisode:ep];
[[seriesList objectAtIndex:[seriesList indexOfObject:tmp]]setBanner:[ep banner]];
}

The binding is done in the subview nib file, to the NSImageView: I set File's Owner of type NSCollectionViewItem and then bind Valueurl to representedObject.banner I didn't subclass NSCollectionView nor NSCollectionViewItem

After days of trying I found a solution that works: apparently it's not enough to use the setString method, I need to re-intialize the property inside the setBanner method

-(void) setBanner:(NSString*)_banner  
 {
     banner = [NSMutableString[NSString stringWithFormat:@"some root path/%@", _banner]];  
 }  

Still, I'd be very glad to know if someone has an explanation of why setString was causing that strange (to me) problem and why this solution works.

Thank you Luca

I'm not sure why you've declared banner to be a mutable string — it looks like an immutable string would suffice.

At any rate, when you write a custom setter method you need to send -willChangeValueForKey: and -didChangeValueForKey: to ensure KVO (and hence bindings) compliance:

-(void) setBanner:(NSString*)_banner
{
    [self willChangeValueForKey:@"banner"];
    [banner setString:[NSString stringWithFormat:@"some root path/%@", _banner];
    [self didChangeValueForKey:@"banner"];

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM