2010-05-19 25 views
0

J'ai un NSTableView qui lie via un NSArrayController à un NSMutableArray. Ce qui est dans le tableau sont des classes dérivées; les premières colonnes de la table sont liées aux propriétés qui existent sur la classe de base. Tout fonctionne bien.Valeurs de colonnes conditionnelles dans NSTableView?

Lorsque je rencontre un problème, une colonne ne doit être remplie que si la ligne correspond à une sous-classe spécifique. La propriété que cette colonne est destinée à afficher n'existe que dans cette sous-classe, car elle n'a aucun sens en termes de classe de base. L'utilisateur saura, à partir des deux premières colonnes, pourquoi la cellule de la troisième colonne est remplie/modifiable ou non.

La liaison sur la valeur de la troisième colonne est placéeObjects, avec un chemin de modèle de quelque chose comme "foo.name" où foo est la propriété de la sous-classe. Toutefois, cela ne fonctionne pas, car les autres sous-classes de la hiérarchie ne sont pas compatibles avec les valeurs-clés pour foo.

Il semble que mon seul choix est d'avoir une propriété foo sur la classe de base afin que tout le monde y réponde, mais cela encombre les interfaces des objets du modèle.

Quelqu'un a-t-il trouvé un design épuré pour cette situation? Il ne peut pas être rare (je suis un nouveau venu relativement à Cocoa et j'apprends juste les tenants et aboutissants des fixations.)

Répondre

1

Une manière de résoudre ceci est d'utiliser seulement des reliures pour les deux premières colonnes où il travaux. Pour les colonnes restantes, vous implémentez un NSTableViewDataSource qui implémente la logique personnalisée nécessaire.

d'abord créer une nouvelle classe qui implémente

-tableView:objectValueForTableColumn:row: 
-tableView:setObjectValue:forTableColumn:row: 

(vous avez seulement besoin 2 si l'utilisateur est censé modifier les autres colonnes). Puis ajoutez un

IBOutlet NSArrayController *valuesController; 

variable d'instance à cette classe. Inside Interface Builder ajoute un nouvel objet de cette classe (faites glisser un cube "objet" bleu dans la fenêtre du fichier à partir de la bibliothèque). Connectez votre contrôleur RAID à votre nouvelle source de données. Connectez ensuite la source de données à la vue de table pour en faire la source de données de la vue table.

Assurez-vous que les colonnes après les deux premiers ne sont liées à rien.

La méthode

-tableView:objectValueForTableColumn:row: 

sera appelé pour les colonnes au besoin et vous pouvez regarder l'objet, au besoin:

- (id)tableView:(NSTableView *)aTableView 
    objectValueForTableColumn:(NSTableColumn *)aTableColumn 
         row:(NSInteger)rowIndex; 
{ 
    NSObject *myObject = [[valuesController arrangedObjects] objectAtIndex:rowIndex]; 
    id columnIdentifier = [aTableColumn identifier]; 
    if ([columnIdentifier isEqual:@"foo"]) { 
     if ([myObject respondsToSelector:@selector(fooValue)]) { 
      return [myObject fooValue]; 
     } 
    } 
    return nil; 
} 

Notez que je suis en utilisant l'identifiant de colonnes pour voir qui la colonne est demandée. Définissez l'identifiant des colonnes dans Interface Builder.