Est-il possible de concevoir des sous-classes NSCell dans Interface Builder?

j'essaie de classer NSCell pour une utilisation dans un NSTableView. La cellule que je veux créer est assez compliquée de sorte qu'il serait très utile si je pouvais le concevoir dans Interface Builder et ensuite charger le NSCell à partir d'un nib.

est-ce possible? Comment dois-je faire?

22
demandé sur JJD 2008-10-14 23:19:55

10 réponses

la question portait sur une sous-classe de NSCell; les autres réponses semblent faire quelque chose d'autre, tirant probablement avantage de la vue utile de Nscell.

NSCell n'est pas une vue. Bien que la mise en place d'une cellule personnalisée dans IB serait une chose utile à être en mesure de faire, je pense que la réponse est fondamentalement "non, ce n'est pas possible". Quand tu classes NSCell, tu fais juste ton propre dessin. Il n'y a pas de subcellules de support, ni de paramétrage automatique (ala NSView springs and struts), qui est je soupçonne ce que vous cherchez.

la seule mise en garde est que vous pourriez concevoir une sous-classe de NSCell que fait faire la disposition des sous-éléments et fourni des paramètres pour le réglage de ces sous-éléments et tous les paramètres tweakable. Ensuite, vous aurez besoin d'écrire un plugin IB pour rendre cette cellule et l'inspecteur d'accompagnement disponible au moment de la conception dans IB.

cela, cependant, est probablement plus difficile que écrire une petite application personnalisée qui fait plus ou moins la même chose. Mettez un NSCell dans un contrôle au milieu d'une fenêtre, et faites-vous L'interface utilisateur pour modifier les paramètres qui vous intéressent. Les reliures peuvent rendre cela assez simple pour positionner des trucs (i.e. lier une valeur x à un slider), bien que vous n'obtiendrez pas de manipulation directe des éléments bien sûr. Lorsque vous avez terminé, vous pouvez archiver votre cellule et charger l'archive à l'exécution dans votre application réelle, ou vous pouvez simplement déconnecter le propriétés et mettez-les en code dans votre application.

11
répondu Ken 2008-10-15 06:59:35

certaines réponses dans ce fil sont allées hors sujet parce qu'ils parlent de Cocoa Touch, quand la question originale était sur le cacao - les 2 API sont tout à fait différents à cet égard et Cocoa Touch rend facile parce que Uitable Viewcell est une sous-classe de vue. NSCell ne l'est pas, et c'est le problème

pour information, j'ai dû faire quelque chose de très similaire dans NSOutlineView récemment - ce qui est fondamentalement le même, mais un peu plus difficile si quelque chose parce que vous avez à traiter de la divulgation / de l'effondrement des niveaux. Si vous êtes intéressé par le code, j'ai posté à ce sujet ici: http://www.stevestreeting.com/2010/08/08/cocoa-tip-using-custom-table-outline-cells-designed-in-ib /

HTH

11
répondu Steve Streeting 2010-08-08 11:28:25

comme Ken le dit, NSCells et NSViews sont différents, et vous pouvez seulement établir NSView hiérarchies dans NIB, pas NSCells (qui n'ont pas de hiérarchie explicite).

d'autre part, il n'y a rien qui vous empêche d'avoir une hiérarchie de NSViews et de l'utiliser pour dessiner votre NSCell -- vous pouvez les ajouter comme sous-vue de la vue parent de votre cellule, leur dire de s'afficher, et les enlever de la fenêtre et personne ne serait le plus sage.

dans ce cas, utiliser un NIB fonctionnerait, bien qu'il semble comme une tonne de tracas. Typiquement, je viens de remplacer l'objet qui prend NSCells par un sur mesure qui prend mon NSViews , mais cela signifie écrire votre propre code de manipulation de souris, qui est très sensible.

d'un autre côté, mon approche vous permet de lier les valeurs des vues dans NIB, de sorte que vous n'avez pas à faire de travail supplémentaire, ce qui est cool.

7
répondu Wil Shipley 2011-11-14 14:20:26

De l'IB, démarrer un vide XIB. Maintenant, allez au pallete et faites glisser dans un utilitaire Viewcell, double clic pour faire apparaître et éditer.

n'incluez que la fonction custom Uitable Viewcell (pas d'autres UIViews ou d'autres contrôles de haut niveau) - assurez-vous qu'il s'agit bien d'une fonction Real Uitable Viewcell en IB, ou vous ne pouvez pas définir un identifiant de réutilisation (par opposition au casting D'UIView en IB en tant que Classe custom Uitable Viewcell). Ensuite, vous pouvez ajouter lables ou ce que vous voulez dans la cellule, ainsi que le réglage de la réutilisation identifiez ou définissez l'indicateur de divulgation que vous souhaitez.

à utiliser, vous fournissez un code comme celui-ci dans le tableView: cellForRow:atIndexPath: method:

YourCustomCellClass *cell = (YourCustomCellClass *)[tableView dequeueReusableCellWithIdentifier:<IDYouSetInXIBFile>];
if ( cell == nil )
{
        NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:<YourXIBName> owner:self options:nil];
    id firstObject = [topLevelObjects objectAtIndex:0];
    if ( [ firstObject isKindOfClass:[UITableViewCell class]] )
        cell = firstObject; 
    else cell = [topLevelObjects objectAtIndex:1];
}

si vous avez des étiquettes ou d'autres contrôles que vous voulez référencer dans votre code, câblez - les en IB à votre classe de cellules personnalisée-pas le propriétaire du fichier, que vous n'avez jamais besoin de définir en utilisant le code ci-dessus (vous pouvez le laisser comme NSObject).

Edit: je note que vous êtes je cherche vraiment une réponse NSCell, mais L'approche du code pour utiliser IB devrait être identique dans Cocoa Touch code que j'ai utilisé ci-dessus car loadNibNamed est un appel standard de Cocoa.

5
répondu Kendall Helmstetter Gelner 2008-10-15 05:03:31

Joar Wingfors a écrit un article pour Stepwise il y a quelques années sur un sujet apparenté, Subviews in TableView Rows .

la technique principale est de créer un NSCell qui peut héberger un NSView. Si vous deviez faire cela, vous pourriez alors concevoir une sous-classe NSView dans Interface Builder que vous pourriez intégrer n'importe où vous avez besoin de cette cellule spécifique.

une autre possibilité, si vous pouvez cibler Leopard, c'est pour voir si vous avez besoin d'utiliser un NSTableView ou si vous pouvez utiliser un NSCollectionView. Les vues de Collection traitent directement en termes de "vues d'item" plutôt que dans les cellules, de sorte qu'elles sont beaucoup plus simples à concevoir dans Interface Builder.

2
répondu Chris Hanson 2008-10-17 00:05:40

j'ai trouvé quelques exemples intéressants que je ne comprends pas totalement, Cependant.

les deux derniers exemples fonctionnent avec NSTableViewDataSource et NSTableViewDelegate . Je voudrais utiliser Bindings et ArrayController dans le InterfaceBuilder pour connecter d'autres éléments D'UI comme des champs de texte.

1
répondu JJD 2017-05-23 10:27:09

je fais comme ça:

/* example of a silly way to load a UITableViewCell from a standalone nib */

+ (CEntryTableViewCell *)cell
{
// TODO -- this is really silly.
NSArray *theObjects = [[NSBundle mainBundle] loadNibNamed:@"EntryTableViewCell" owner:self options:NULL];
for (id theObject in theObjects)
    if ([theObject isKindOfClass:self])
        return(theObject);
NSAssert(NO, @"Could not find object of class CEntryTableViewCell in nib");
return(NULL);
}

cependant, il n'est pas très efficace et si vous chargez beaucoup de données, il pourrait vous nuire. Bien sûr, vous devriez utiliser un reuseIdentifier qui devrait forcer ce code à exécuter seulement une poignée de fois par table.

0
répondu schwa 2008-10-15 00:08:34

1) Créer NSViewController TableViewCell.h

2) Créer dans TableViewCell.h certaines procédures comme

-(void)setText:(NSString *)text image:(NSImage *)image

3) dans la classe principale #import "TableViewCell.h"

4) dans la classe principale dans -(NSView *)tableView:viewForTableColumn:row: write:

NSImage *img = //some image
TableViewCell *cell = [[TableViewCell alloc] initWithWindowNibName:@"TableViewCell"];
cell.view.init;
[cell setText:@"some text" image:img];
return cell;

Espérons que cela aidera =)

0
répondu supertrall 2013-06-05 10:48:55

je veux fournir une approche plus moderne ici.

à partir de iOS 5, UITableView a une méthode

(void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier

une fois que vous avez enregistré votre NIB contenant votre cellule, il vous suffit d'utiliser

- (id)dequeueReusableCellWithIdentifier:(NSString *)identifier

pour avoir une nouvelle cellule. Si une cellule est disponible pour la réutilisation, il sera retourné, sinon une nouvelle cellule est automatiquement créé, et dans ce cas cela signifie chargé de la PLUME fichier.

0
répondu Mecki 2014-05-07 10:48:15

ajoutez votre UITableViewCell à votre tableviewcontroller et déclarez un IBOutlet bien:

@interface KuguTableViewController : UITableViewController {
    IBOutlet UITableViewCell *customTypeCell;
}

@property (readonly)  UITableViewCell *customTypeCell;

... puis dans cellForRowAtIndexPath vous pouvez simplement utiliser votre cellule et la régler pour qu'elle soit réutilisée:

static NSString *CellIdentifier = @"CustomCell"
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
        cell = customTypeCell;
        cell.reuseIdentifier = CellIdentifier;
-1
répondu Jason Plank 2011-11-14 14:19:09