2010-05-19 27 views
0

Dans mon code, je stocke une image dans mon modèle de données de base (fonctionne très bien). Si je configure mon point de vue pour avoir un NSImageView et lier ses données à la clé du contrôleur: selection et modelKeyPath: myImagePath, cela fonctionne. Il montrera chaque image pour la rangée sélectionnée. Je crée ensuite une nouvelle colonne dans mon NSTableView et fais glisser une cellule d'image sur la colonne. Cependant, je ne peux pas obtenir mes liaisons de données de base pour que l'image apparaisse dans la cellule. J'ai essayé de lier à la fois la valeur et les données, mais pas de chance. Comme je suis sûr que l'image est correctement stockée, qu'est-ce que je fais de mal dans ma reliure pour empêcher l'image d'apparaître dans la cellule du tableau?L'image de données de base ne se charge pas dans la cellule d'image NSTableView

Merci beaucoup.

(Mon arrière-plan. Nouveau développeur Cocoa qui a récemment passé à travers tout le livre Hillegass)

Répondre

2

Je ne suis pas sûr de ce qui se passe à cause de votre problème, mais il y a un moyen facile de savoir. Raccordez un NSValueTransformer à la liaison. Ensuite, dans ce transformateur, vous pouvez enregistrer des données pour savoir si vous transmettez une valeur nulle, ou vous pouvez transformer votre valeur de données en NSImage et la renvoyer ... En gros, vous pouvez faire ce que vous voulez dans la classe transformateur. En voici un que j'utilise sur les données d'image dans un modèle de données de base.

@interface DataToImageTransformer : NSValueTransformer { 

} 

@end 


@implementation DataToImageTransformer 

+ (Class)transformedValueClass { 
    return [NSImage class]; 
} // the class of the return value from transformedValue: 

+ (BOOL)allowsReverseTransformation { 
    return YES; 
} // if YES then must also have reverseTransformedValue: 

- (id)transformedValue:(id)value { 
    if (value == nil || [value length] < 1) return nil; 
    NSImage* i = nil; 
    if ([value isKindOfClass:[NSData class]]) { 
     i = [NSKeyedUnarchiver unarchiveObjectWithData:value]; 
    } 
    return i; 
} 

- (id)reverseTransformedValue:(id)value { 
    if (value == nil) return nil; 
    NSData* d = nil; 
    if ([value isKindOfClass:[NSImage class]]) { 
     d = [NSKeyedArchiver archivedDataWithRootObject:value]; 
    } 
    return d; 
} 

@end 

En classe AppController vous initialisez le transformateur:

+ (void)initialize { 
    DataToImageTransformer *transformer = [[DataToImageTransformer alloc] init]; 
    [NSValueTransformer setValueTransformer:transformer forName:@"DataToImageTransformer"]; 
    [transformer release]; 
} 

Ensuite, dans Interface Builder vous mettre "DataToImageTransformer" dans la liaison. Maintenant vous avez le contrôle sur la liaison et pouvez faire ce que j'ai expliqué plus tôt dans la classe du transformateur. Notez que j'utilise NSKeyedArchiver pour convertir un NSImage en données et revenir en arrière, mais vous pouvez utiliser tiffRepresentation ou toute autre méthode que vous voulez à sa place.

+0

Merci, cela a fonctionné! Le seul problème est que j'obtiens un avertissement obsolète en liant des données à un NSTableColumn. Mais votre stratégie consistant à enregistrer les données d'image à l'aide de NSKeyedArchiver et à les récupérer à l'aide de ce transformateur a été couronnée de succès. – jcady

+0

Je me souviens de quelque chose à propos de l'une des attaches étant obsolète, utilisez donc l'autre liaison à la place ... est-ce la valeur de liaison? Vous pouvez probablement utiliser ceci avec cette liaison aussi, et si ce n'est pas juste modifier le transformateur comme nécessaire pour retourner tous les objets nécessaires. – regulus6633

0

Si quelqu'un rencontre des problèmes avec la technique suggérée avec Xcode 6. J'ai créé un projet Swift en utilisant l'application Document based. Avec un contrôle ImageWell (NSImageView), les liaisons fonctionnent directement sans valeur le besoin d'un transformateur. Un détail cependant, vous mettre en liaison sur la liaison de données de la vue elle-même, pas sur l'objet ImageCell en dessous.