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?
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.
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
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.
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.
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.
j'ai trouvé quelques exemples intéressants que je ne comprends pas totalement, Cependant.
- GitX prolonge le
NSTextFieldCell
dans leur Pbiconettextcell , en faisant référence à ce post . - de la WWDC 2009 - Session 110 ", Présentant les Données de l'Utilisateur avec les Vues de Table et les Navigateurs" parle "en Ajoutant des sous-vues" et "cellule Personnalisé éditeurs". (Je n'ai pas le code source.)
- Afficher une NSTextfieldCell contenant du texte et une image au sein d'un NSTableView, #70
- afficher un NSTextfieldCell contenant du texte et une image dans NSTableView, #71
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.
-
je suis tombé dans une autre discussion où Abizern souligne PXListView par Alex Rozanski qui a l'air très prometteur!
-
j'essaie moi-même de trouver une solution au problème. S'il vous plaît trouver mon projet sur github et le dernier problèmes de rendu ici .
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.
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 =)
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.
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;