UITableView
défini sur des cellules statiques.
Est-il possible de masquer certaines des cellules par programme?
ios
objective-c
uitableview
Shmidt
la source
la source
IBOutletCollection
mais je ne vois pas en quoi cela ferait une différence. Je n'ai téléchargé le code qu'hier, donc je ne pense pas que ce soit une ancienne version.Pour masquer les cellules statiques dans UITable:
Dans votre classe de délégué de contrôleur UITableView:
Objectif c:
Rapide:
Cette méthode sera appelée pour chaque cellule de l'UITable. Une fois qu'il l'appelle pour la cellule que vous souhaitez masquer, nous définissons sa hauteur sur 0. Nous identifions la cellule cible en lui créant une sortie:
la source
ClipToBounds
problème, vous pouvez également définir la cellule sur masquée. Cela me paraîtrait plus propre. ;-)Le meilleur moyen est celui décrit dans le blog suivant http://ali-reynolds.com/2013/06/29/hide-cells-in-static-table-view/
la source
Ma solution va dans le même sens que Gareth, bien que je fasse certaines choses différemment.
Voici:
1. Cachez les cellules
Il n'y a aucun moyen de masquer directement les cellules.
UITableViewController
est la source de données qui fournit les cellules statiques, et actuellement il n'y a aucun moyen de lui dire "ne pas fournir la cellule x". Nous devons donc fournir notre propre source de données, qui délègue auUITableViewController
afin d'obtenir les cellules statiques.Le plus simple est de sous
UITableViewController
-classer et de remplacer toutes les méthodes qui doivent se comporter différemment lors du masquage de cellules .Dans le cas le plus simple (table à section unique, toutes les cellules ont la même hauteur), cela ressemblerait à ceci:
Si votre tableau comporte plusieurs sections ou si les cellules ont des hauteurs différentes, vous devez remplacer d'autres méthodes. Le même principe s'applique ici: vous devez décaler indexPath, section et row avant de déléguer à super.
Gardez également à l'esprit que le paramètre indexPath pour des méthodes telles que
didSelectRowAtIndexPath:
sera différent pour la même cellule, en fonction de l'état (c'est-à-dire le nombre de cellules masquées). C'est donc probablement une bonne idée de toujours compenser tout paramètre indexPath et de travailler avec ces valeurs.2. Animer le changement
Comme Gareth l'a déjà déclaré, vous obtenez des problèmes majeurs si vous animez les modifications à l'aide de la
reloadSections:withRowAnimation:
méthode.J'ai découvert que si vous appelez
reloadData:
immédiatement après, l'animation est beaucoup améliorée (il ne reste que de petits problèmes). Le tableau s'affiche correctement après l'animation.Donc ce que je fais, c'est:
la source
numberOfRowsInSection:
sont appelées uniquement lorsque la table se charge pour la première fois. Quand j'appelle [self.tableView reloadData] -numberOfRowsInSection:
n'est plus jamais appelé. SeulcellForRowAtIndexPath:
est appelé. Qu'est-ce que je rate?cellOneOutlet.hidden = true
remplacez maintenant la méthode ci-dessous, vérifiez quel état de cellule est masqué et renvoyez la hauteur 0 pour ces cellules. C'est l'une des nombreuses façons de masquer n'importe quelle cellule dans tableView statique dans Swift.
la source
let tableViewCell = super.tableView(tableView,cellForRowAtIndexPath: indexPath)
. Je suppose qu'il est remplacé parlet tableViewCell = tableView.cellForRow(at: indexPath as IndexPath)
.UITableViewController
, je n'ai aucuneUITableView
méthode de délégation. Pour pouvoir l'appelerheightForRow
, ai-je également besoin d'autres méthodes?J'ai trouvé une alternative qui cache en fait les sections et ne les supprime pas. J'ai essayé l'approche de @ henning77, mais j'ai continué à rencontrer des problèmes lorsque j'ai changé le nombre de sections de l'UITableView statique. Cette méthode a très bien fonctionné pour moi, mais j'essaie principalement de masquer des sections au lieu de lignes. Je supprime certaines lignes à la volée avec succès, mais c'est beaucoup plus compliqué, j'ai donc essayé de regrouper les choses en sections que je dois afficher ou masquer. Voici un exemple de la façon dont je cache des sections:
Je déclare d'abord une propriété NSMutableArray
Dans le viewDidLoad (ou après avoir interrogé vos données), vous pouvez ajouter des sections que vous souhaitez masquer au tableau.
Ensuite, implémentez les méthodes de délégué TableView suivantes
Ensuite, définissez la hauteur de l'en-tête et du pied de page sur 1 pour les sections masquées car vous ne pouvez pas définir la hauteur sur 0. Cela entraîne un espace supplémentaire de 2 pixels, mais nous pouvons le compenser en ajustant la hauteur de l'en-tête visible suivant.
Ensuite, si vous avez des lignes spécifiques à masquer, vous pouvez ajuster le numberOfRowsInSection et les lignes renvoyées dans cellForRowAtIndexPath. Dans cet exemple, j'ai une section qui comporte trois lignes où trois d'entre elles peuvent être vides et doivent être supprimées.
Utilisez ce offsetIndexPath pour calculer l'indexPath pour les lignes où vous supprimez conditionnellement des lignes. Pas nécessaire si vous ne masquez que des sections
Il existe de nombreuses méthodes à remplacer, mais ce que j'aime dans cette approche, c'est qu'elle est réutilisable. Configurez le tableau hiddenSections, ajoutez-y et il masquera les sections correctes. Cacher les rangées c'est un peu plus délicat, mais possible. Nous ne pouvons pas simplement définir la hauteur des lignes que nous voulons masquer à 0 si nous utilisons un UITableView groupé car les bordures ne seront pas dessinées correctement.
la source
NSMutableSet
pour à lahiddenSections
place. C'est beaucoup plus rapide car vous testez principalement l'adhésion.NSMutableSet
forhiddenSections
, même si je comprends que le point de votre réponse était plus conceptuel que pointilleux quant au type de structure de données à utiliser.Il s'avère que vous pouvez masquer et afficher des cellules dans un UITableView statique - et avec une animation. Et ce n'est pas si difficile à accomplir.
Projet de démonstration
Vidéo du projet de démonstration
L'essentiel:
Use tableView:heightForRowAtIndexPath:
pour spécifier les hauteurs de cellule de manière dynamique en fonction d'un état.tableView.beginUpdates();tableView.endUpdates()
tableView.cellForRowAtIndexPath:
intérieurtableView:heightForRowAtIndexPath:
. Utilisez les indexPaths mis en cache pour différencier les cellules.Plus d'informations dans mon blog (langue russe)
la source
Oui, c'est certainement possible, même si je suis aux prises avec le même problème pour le moment. J'ai réussi à masquer les cellules et tout fonctionne bien, mais je ne peux pas actuellement faire en sorte que la chose s'anime proprement. Voici ce que j'ai trouvé:
Je cache des lignes en fonction de l'état d'un interrupteur ON / OFF dans la première ligne de la première section. Si le commutateur est sur ON, il y a 1 ligne en dessous dans la même section, sinon il y a 2 lignes différentes.
J'ai un sélecteur appelé lorsque le commutateur est basculé, et je règle une variable pour indiquer dans quel état je me trouve. Ensuite, j'appelle:
Je remplace la tableView: willDisplayCell: forRowAtIndexPath: function et si la cellule est censée être masquée, je fais ceci:
Cela masque la cellule et son contenu, mais ne supprime pas l'espace qu'elle occupe.
Pour supprimer l'espace, remplacez la tableView: heightForRowAtIndexPath: function et renvoyez 0 pour les lignes qui doivent être masquées.
Vous devez également remplacer tableView: numberOfRowsInSection: et renvoyer le nombre de lignes dans cette section. Vous devez faire quelque chose d'étrange ici pour que si votre tableau est un style groupé, les coins arrondis apparaissent sur les cellules correctes. Dans mon tableau statique, il y a l'ensemble complet de cellules pour la section, donc il y a la première cellule contenant l'option, puis 1 cellule pour les options d'état ON et 2 autres cellules pour les options d'état OFF, un total de 4 cellules. Lorsque l'option est activée, je dois retourner 4, cela inclut l'option masquée afin que la dernière option affichée ait une boîte arrondie. Lorsque l'option est désactivée, les deux dernières options ne sont pas affichées, donc je retourne 2. Tout cela semble maladroit. Désolé si ce n'est pas très clair, c'est difficile à décrire. Juste pour illustrer la configuration, voici la construction de la section de table dans IB:
Ainsi, lorsque l'option est activée, le tableau indique deux lignes qui sont:
Lorsque l'option est désactivée, le tableau indique quatre lignes qui sont:
Cette approche ne semble pas correcte pour plusieurs raisons, c'est tout ce que j'ai obtenu avec mon expérimentation jusqu'à présent, alors faites-moi savoir si vous trouvez un meilleur moyen. Les problèmes que j'ai observés jusqu'à présent sont:
Il est faux de dire à la table que le nombre de lignes est différent de ce qui est vraisemblablement contenu dans les données sous-jacentes.
Je n'arrive pas à animer le changement. J'ai essayé d'utiliser tableView: reloadSections: withRowAnimation: au lieu de reloadData et les résultats ne semblent pas avoir de sens, j'essaie toujours de faire fonctionner cela. Actuellement, ce qui semble se produire, c'est que tableView ne met pas à jour les lignes correctes, donc l'une reste cachée qui doit être affichée et un vide est laissé sous la première ligne. Je pense que cela pourrait être lié au premier point concernant les données sous-jacentes.
J'espère que quelqu'un pourra suggérer des méthodes alternatives ou peut-être comment étendre avec l'animation, mais peut-être que cela vous aidera à démarrer. Mes excuses pour le manque d'hyperliens vers les fonctions, je les ai mis mais ils ont été rejetés par le filtre anti-spam car je suis un utilisateur assez récent.
la source
[[self tableView] reloadData];
une fois de plus après avoir caché les cellulesreturn [super tableView:tableView cellForRowAtIndexPath:indexPath];
sous-UITableViewController
classe pour créer des cellules statiques. Les chemins d'index sont indexés statiquement - pas dynamiques ...Selon la réponse de Justas, mais pour Swift 4:
la source
tableView.reloadRows(at:, with:)
mettre à jour les cellules si vous modifiez la hauteur alors que la ligne est déjà visible.D'accord, après quelques essais, j'ai une réponse non commune. J'utilise la variable "isHidden" ou "hidden" pour vérifier si cette cellule doit être masquée.
créez un IBOutlet dans votre contrôleur de vue.
@IBOutlet weak var myCell: UITableViewCell!
Mettez à jour le
myCell
dans votre fonction personnalisée, par exemple, vous pouvez l'ajouter dans viewDidLoad:override func viewDidLoad() { super.viewDidLoad() self.myCell.isHidden = true }
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { let cell = super.tableView(tableView, cellForRowAt: indexPath) guard !cell.isHidden else { return 0 } return super.tableView(tableView, heightForRowAt: indexPath) }
Cela réduira votre logique dans la méthode de délégué et vous n'aurez qu'à vous concentrer sur vos besoins commerciaux.
la source
Les réponses ci-dessus qui masquent / affichent les cellules, modifient rowHeight ou gâchent les contraintes de mise en page automatique ne fonctionnaient pas pour moi en raison de problèmes de mise en page automatique. Le code est devenu intolérable.
Pour une simple table statique, ce qui fonctionnait le mieux pour moi était de:
Voici un exemple de mon contrôleur de vue de table:
la source
Méthode simple compatible iOS 11 et IB / Storyboard
Pour iOS 11, j'ai trouvé qu'une version modifiée de la réponse de Mohamed Saleh fonctionnait le mieux, avec quelques améliorations basées sur la documentation d'Apple. Il s'anime bien, évite les hacks ou les valeurs codées en dur et utilise des hauteurs de ligne déjà définies dans Interface Builder .
Le concept de base est de définir la hauteur de ligne sur 0 pour toutes les lignes masquées. Utilisez ensuite
tableView.performBatchUpdates
pour déclencher une animation qui fonctionne de manière cohérente.Définir les hauteurs de cellule
Vous voudrez vous assurer
cellIsHidden
etindexPathOfHiddenCell
sont définis de manière appropriée à votre cas d'utilisation. Pour mon code, ce sont des propriétés sur mon contrôleur de vue table.Basculer la cellule
Quelle que soit la méthode qui contrôle la visibilité (probablement une action de bouton ou
didSelectRow
), basculez l'état cellIsHidden, à l'intérieur d'unperformBatchUpdates
bloc:Apple recommande
performBatchUpdates
plusbeginUpdates
/endUpdates
chaque fois que possible.la source
J'ai trouvé une solution pour animer les cellules de masquage dans un tableau statique.
Un seul dictionnaire supplémentaire nécessaire:
Et regardez l'implémentation de MyTableViewController. Nous avons besoin de deux méthodes pour convertir indexPath entre les index visibles et invisibles ...
Une IBAction sur la modification de la valeur UISwitch:
Certaines méthodes UITableViewDataSource et UITableViewDelegate:
la source
Répondez rapidement :
Ajoutez la méthode suivante dans votre TableViewController:
si le tableView essaie de dessiner la cellule que vous souhaitez masquer, il ne l'affichera pas car sa hauteur sera fixée à 0pt grâce à la méthode ci-dessus, tout le reste reste inchangé.
Veuillez noter que cela
indexPathOfCellYouWantToHide
peut être modifié à tout moment :)la source
Dans> Swift 2.2, j'ai combiné quelques réponses ici.
Créez une sortie à partir du storyboard pour créer un lien vers votre staticCell.
Je veux masquer ma première cellule, donc je règle la hauteur sur 0 comme décrit ci-dessus.
la source
Swift 4:
la source
Pour le scénario le plus simple lorsque vous masquez des cellules tout en bas de la vue tableau, vous pouvez ajuster le contentInset de tableView après avoir masqué la cellule:
la source
C'est une nouvelle façon de faire cela en utilisant https://github.com/k06a/ABStaticTableViewController
la source
La solution de k06a ( https://github.com/k06a/ABStaticTableViewController ) est meilleure car elle cache toute la section, y compris les en-têtes et les pieds de page des cellules, où cette solution ( https://github.com/peterpaulis/StaticDataTableViewController ) cache tout sauf le pied de page.
ÉDITER
Je viens de trouver une solution si vous souhaitez masquer le pied de page
StaticDataTableViewController
. Voici ce que vous devez copier dans le fichier StaticTableViewController.m:la source
Vous pouvez sûrement. Tout d'abord, revenez à votre tableau Afficher le nombre de cellules que vous souhaitez afficher, puis appelez
super
pour obtenir une certaine cellule de votre storyboard et renvoyez-le pour tableView:Si vos cellules ont une hauteur différente, renvoyez-la également:
la source
En plus de la solution @Saleh Masum:
Si vous obtenez des erreurs de mise en page automatique , vous pouvez simplement supprimer les contraintes du
tableViewCell.contentView
Swift 3:
Cette solution dépend du flux de votre application . Si vous souhaitez afficher / masquer la cellule dans la même instance de contrôleur de vue, ce n'est peut-être pas le meilleur choix, car cela supprime les contraintes .
la source
J'ai eu un meilleur moyen de masquer les cellules statiques et même les sections de manière dynamique sans aucun piratage.
La définition de la hauteur de ligne à 0 peut masquer une ligne, mais cela ne fonctionne pas si vous souhaitez masquer une section entière qui contiendra des espaces même si vous masquez toutes les lignes.
Mon approche consiste à créer un tableau de sections de cellules statiques. Ensuite, le contenu de la vue de table sera piloté par le tableau de sections.
Voici un exemple de code:
De cette façon, vous pouvez rassembler tout votre code de configuration sans avoir à écrire le mauvais code pour calculer le nombre de lignes et de sections. Et bien sûr, non
0
hauteurs.Ce code est également très facile à maintenir. Par exemple, si vous souhaitez ajouter / supprimer d'autres cellules ou sections.
De même, vous pouvez créer un tableau de titre d'en-tête de section et un tableau de titre de pied de page pour configurer dynamiquement vos titres de section.
la source