Si je comprends bien, vous voulez:
- Concevez une cellule dans IB qui peut être utilisée dans plusieurs scènes de storyboard.
- Configurez des séquences de storyboard uniques à partir de cette cellule, selon la scène dans laquelle se trouve la cellule.
Malheureusement, il n'y a actuellement aucun moyen de le faire. Pour comprendre pourquoi vos tentatives précédentes n'ont pas fonctionné, vous devez en savoir plus sur le fonctionnement des storyboards et des cellules de vue de tableau prototype. (Si vous ne vous souciez pas de la raison pour laquelle ces autres tentatives n'ont pas fonctionné, n'hésitez pas à partir maintenant. Je n'ai aucune solution de contournement magique pour vous, à part suggérer que vous signaliez un bogue.)
Un storyboard n'est, par essence, pas beaucoup plus qu'une collection de fichiers .xib. Lorsque vous chargez un contrôleur de vue de table contenant des cellules prototypes dans un storyboard, voici ce qui se passe:
- Chaque cellule prototype est en fait sa propre mini-pointe intégrée. Ainsi, lorsque le contrôleur de vue de table est en cours de chargement, il parcourt chacune des nibs et appels de la cellule prototype
-[UITableView registerNib:forCellReuseIdentifier:]
.
- La vue tableau demande au contrôleur les cellules.
- Vous appelez probablement
-[UITableView dequeueReusableCellWithIdentifier:]
Lorsque vous demandez une cellule avec un identifiant de réutilisation donné, il vérifie si elle a une plume enregistrée. Si c'est le cas, il instancie une instance de cette cellule. Il se compose des étapes suivantes:
- Regardez la classe de la cellule, telle que définie dans la pointe de la cellule. Appelle
[[CellClass alloc] initWithCoder:]
.
- La
-initWithCoder:
méthode passe par et ajoute des sous-vues et définit les propriétés qui ont été définies dans la nib. ( IBOutlet
Je suis probablement aussi connecté ici, même si je n'ai pas testé cela; cela peut arriver en -awakeFromNib
)
Vous configurez votre cellule comme vous le souhaitez.
La chose importante à noter ici est qu'il y a une distinction entre la classe de la cellule et l' apparence visuelle de la cellule. Vous pouvez créer deux cellules prototypes distinctes de la même classe, mais avec leurs sous-vues disposées de manière complètement différente. En fait, si vous utilisez les UITableViewCell
styles par défaut , c'est exactement ce qui se passe. Le style "Default" et le style "Subtitle", par exemple, sont tous deux représentés par la même UITableViewCell
classe.
Ceci est important : la classe de la cellule n'a pas de corrélation un à un avec une hiérarchie de vues particulière . La hiérarchie des vues est entièrement déterminée par ce qui se trouve dans la cellule prototype qui a été enregistrée avec ce contrôleur particulier.
Notez également que l'identifiant de réutilisation de la cellule n'a pas été enregistré dans certains dispensaires cellulaires mondiaux. L'identifiant de réutilisation n'est utilisé que dans le contexte d'une seule UITableView
instance.
Compte tenu de ces informations, regardons ce qui s'est passé lors de vos tentatives ci-dessus.
Dans le contrôleur n ° 1, ajouté une cellule prototype, définissez la classe sur ma sous-classe UITableViewCell, définissez l'ID de réutilisation, ajoutez les étiquettes et connectez-les aux prises de la classe. Dans le contrôleur n ° 2, ajouté une cellule prototype vide, définissez-la sur la même classe et réutilisez l'identifiant comme précédemment. Lorsqu'il s'exécute, les étiquettes n'apparaissent jamais lorsque les cellules sont affichées dans le contrôleur n ° 2. Fonctionne bien dans le contrôleur # 1.
C'est attendu. Bien que les deux cellules aient la même classe, la hiérarchie de vues transmise à la cellule du contrôleur n ° 2 était entièrement dépourvue de sous-vues. Vous avez donc une cellule vide, ce qui est exactement ce que vous avez mis dans le prototype.
Conçu chaque type de cellule dans un NIB différent et câblé à la classe de cellule appropriée. Dans le storyboard, ajouté une cellule prototype vide et défini sa classe et son identifiant de réutilisation pour faire référence à ma classe de cellule. Dans les méthodes viewDidLoad des contrôleurs, enregistré ces fichiers NIB pour l'ID de réutilisation. Lorsque montré, les cellules des deux contrôleurs étaient vides comme le prototype.
Encore une fois, cela est prévu. L'identifiant de réutilisation n'est pas partagé entre les scènes du storyboard ou les nibs, donc le fait que toutes ces cellules distinctes avaient le même identifiant de réutilisation n'a pas de sens. La cellule que vous récupérez de la table aura une apparence qui correspond à la cellule prototype dans cette scène du storyboard.
Cette solution était pourtant proche. Comme vous l'avez noté, vous pouvez simplement appeler par programme -[UITableView registerNib:forCellReuseIdentifier:]
, en passant UINib
la cellule contenant la cellule, et vous récupérez cette même cellule. (Ce n'est pas parce que le prototype "remplaçait" la plume; vous n'aviez tout simplement pas enregistré la plume avec la table, donc il regardait toujours la plume intégrée dans le storyboard.) Malheureusement, il y a un défaut avec cette approche - il n'y a aucun moyen de connecter les séquences de storyboard à une cellule dans une plume autonome.
Les prototypes conservés dans les deux contrôleurs sont vides et définissent la classe et réutilisent l'ID dans ma classe de cellule. Construit l'interface utilisateur des cellules entièrement en code. Les cellules fonctionnent parfaitement dans tous les contrôleurs.
Naturellement. Espérons que ce ne soit pas surprenant.
Voilà pourquoi cela n'a pas fonctionné. Vous pouvez concevoir vos cellules dans des plumes autonomes et les utiliser dans plusieurs scènes de storyboard; vous ne pouvez pas actuellement connecter de séquences de storyboard à ces cellules. Espérons que vous ayez appris quelque chose en lisant ceci.
Malgré l'excellente réponse de BJ Homer, j'ai l'impression d'avoir une solution. En ce qui concerne mes tests, cela fonctionne.
Concept: créer une classe personnalisée pour la cellule xib. Là, vous pouvez attendre un événement tactile et effectuer la séquence par programme. Maintenant, tout ce dont nous avons besoin est une référence au contrôleur effectuant la séquence. Ma solution est de l'installer
tableView:cellForRowAtIndexPath:
.Exemple
J'ai une
DetailedTaskCell.xib
cellule contenant une table que j'aimerais utiliser dans plusieurs vues de table:Il existe une classe personnalisée
TaskGuessTableCell
pour cette cellule:C'est là que la magie opère.
J'ai plusieurs Segues mais ils ont tous le même nom:
"FinishedTask"
. Si vous devez être flexible ici, je vous suggère d'ajouter une autre propriété.Le ViewController ressemble à ceci:
Il pourrait y avoir des façons plus élégantes de faire la même chose, mais - cela fonctionne! :)
la source
-setSelected:
la cellule et de déclencher la séquence uniquement lors de la transition deNO
àYES
.setSelected:
BJ. Merci. En effet, c'est une solution inélégante (cela semble mal), mais en même temps, cela fonctionne, donc je l'utilise jusqu'à ce que cela soit corrigé (ou quelque chose change dans la cour d'Apple).Je cherchais cela et j'ai trouvé cette réponse de Richard Venable. Ça marche pour moi.
la source
BJ Homer a donné une excellente explication de ce qui se passe.
D'un point de vue pratique, j'ajouterais que, étant donné que vous ne pouvez pas avoir de cellules en tant que xibs ET connecter des séquences, le meilleur choix est d'avoir la cellule en tant que xib - les transitions sont beaucoup plus faciles à maintenir que les dispositions et les propriétés des cellules à plusieurs endroits , et vos séquences seront probablement différentes de vos différents contrôleurs de toute façon. Vous pouvez définir la séquence directement depuis votre contrôleur de vue de table vers le contrôleur suivant et l'exécuter en code. .
Une autre note est que le fait d'avoir votre cellule en tant que fichier xib séparé vous empêche de pouvoir connecter des actions, etc. directement au contrôleur de vue de table (je n'ai pas travaillé, de toute façon - vous ne pouvez pas définir le propriétaire du fichier comme quelque chose de significatif ). Je travaille autour de cela en définissant un protocole auquel le contrôleur de vue de table de la cellule est censé se conformer et en ajoutant le contrôleur en tant que propriété faible, similaire à un délégué, dans cellForRowAtIndexPath.
la source
Swift 3
BJ Homer a donné une excellente explication, cela m'aide à comprendre le concept. To
make a custom cell reusable in storyboard
, qui peut être utilisé dans n'importe quel TableViewController que nous devonsmix the Storyboard and xib
approcher. Supposons que nous ayons une cellule nommée asCustomCell
qui doit être utilisée dans leTableViewControllerOne
etTableViewControllerTwo
. Je le fais par étapes.1. Fichier> Nouveau> Cliquez sur Fichier> Sélectionner la classe Cocoa Touch> cliquez sur Suivant> Donnez le nom de votre classe (par exemple
CustomCell
)> sélectionnez Sous-classe comme UITableVieCell> Cochez la case également créer un fichier XIB et appuyez sur Suivant.2. Personnalisez la cellule comme vous le souhaitez et définissez l'identifiant dans l'inspecteur d'attributs pour la cellule, ici nous allons définir comme
CellIdentifier
. Cet identifiant sera utilisé dans votre ViewController pour identifier et réutiliser la cellule.3. Il ne nous reste plus qu'à
register this cell
dans notre ViewControllerviewDidLoad
. Pas besoin de méthode d'initialisation.4. Nous pouvons maintenant utiliser cette cellule personnalisée dans n'importe quelle tableView.
Dans TableViewControllerOne
la source
J'ai trouvé un moyen de charger la cellule pour le même VC, non testé pour les séquences. Cela pourrait être une solution de contournement pour créer la cellule dans une pointe séparée
Disons que vous avez un VC et 2 tableaux et que vous souhaitez concevoir une cellule dans le storyboard et l'utiliser dans les deux tableaux.
(ex: une table et un champ de recherche avec un UISearchController avec une table pour les résultats et vous souhaitez utiliser la même cellule dans les deux)
Lorsque le contrôleur demande la cellule, procédez comme suit:
Et ici, vous avez votre cellule du storyboard
la source
tableView:cellForRowAtIndexPath:
).