UITableView
ensemble de cellules statiques.
Est-il possible de masquer une partie des cellules par programmation?
UITableView
ensemble de cellules statiques.
Est-il possible de masquer une partie des cellules par programmation?
Si vous n'avez pas de soins sur les animations et vous voulez juste pour masquer les cellules statiques, ajoutez ceci à votre UITableView contrôleur délégué de classe:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell* cell = [super tableView:tableView cellForRowAtIndexPath:indexPath];
if(cell == this.cellYouWantToHide)
return 0; //set the hidden cell's height to 0
else
return [super tableView:tableView heightForRowAtIndexPath:indexPath];
}
Où cela.cellYouWantToHide est une cellule référencée par une prise de courant dans le concepteur.
Gardez à l'esprit, les cellules se cachent besoin d'avoir ClipToBounds = OUI (appelé "Clip des sous-vues" de l'IB). Sinon, le texte va s'accumuler dans la UITableView.
Vous êtes à la recherche pour cette solution :
StaticDataTableViewController 2.0
https://github.com/xelvenone/StaticDataTableViewController
qui peut afficher/masquer/de recharger un cellulaire statique(s) avec ou sans animation!
[self cell:self.outletToMyStaticCell1 setHidden:hide];
[self cell:self.outletToMyStaticCell2 setHidden:hide];
[self reloadDataAnimated:YES];
Note de toujours utiliser uniquement (reloadDataAnimated:OUI/NON) (ne pas appeler [auto.tableView reloadData] directement)
Le meilleur moyen est tel que décrit dans le blog suivant http://ali-reynolds.com/2013/06/29/hide-cells-in-static-table-view/
La conception de votre tableau statique vue comme normale dans interface builder – complet avec tous potentiellement des cellules masquées. Mais il est une chose que vous doit le faire pour toutes les cellules que vous souhaitez masquer, – vérifier l' "Clip des sous-vues" de la propriété de la cellule, sinon le contenu de la la cellule ne disparaissent pas lorsque vous essayez de le cacher (par diminution de la il est hauteur – plus tard).
SI vous avez un interrupteur dans une cellule et que l'interrupteur est censée cacher et de montrer quelques cellules statiques. De le raccorder à une IBAction et il ne ce:
[self.tableView beginUpdates]; [self.tableView endUpdates];
Qui vous donne de jolies animations pour les cellules qui apparaissent et en voie de disparition. Maintenant mettre en œuvre le tableau suivant afficher le délégué de la méthode:
- (float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.section == 1 && indexPath.row == 1) { // This is the cell to hide - change as you need // Show or hide cell if (self.mySwitch.on) { return 44; // Show the cell - adjust the height as you need } else { return 0; // Hide the cell } } return 44; }
Et c'est tout. Basculez l'interrupteur et la cellule de cuirs et réapparaît avec une nice, une animation fluide.
Ma solution va dans la même direction que Gareth, si j'ai à faire certaines choses différemment.
Va ici:
1. Masquer les cellules
Il n'y a aucun moyen de directement de masquer les cellules. UITableViewController
est la source de données qui fournit les cellules statiques, et il n'existe actuellement aucun moyen de dire "ne pas fournir de la cellule x".
Donc, nous devons donner notre propre source de données, qui délègue à l' UITableViewController
afin d'obtenir les cellules statiques.
Le plus simple est de la sous-classe UITableViewController
, et de remplacer toutes les méthodes qui doivent se comporter différemment lorsque le masquage des cellules.
Dans le cas le plus simple (une seule section de table, toutes les cellules ont la même hauteur), ce serait aller comme ceci:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [super tableView:tableView numberOfRowsInSection:section] - numberOfCellsHidden;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Recalculate indexPath based on hidden cells
indexPath = [self offsetIndexPath:indexPath];
return [super tableView:tableView cellForRowAtIndexPath:indexPath];
}
- (NSIndexPath*)offsetIndexPath:(NSIndexPath*)indexPath
{
int offsetSection = indexPath.section; // Also offset section if you intend to hide whole sections
int numberOfCellsHiddenAbove = ... // Calculate how many cells are hidden above the given indexPath.row
int offsetRow = indexPath.row + numberOfCellsHiddenAbove;
return [NSIndexPathindexPathForRow:offsetRow inSection:offsetSection];
}
Si votre tableau comporte plusieurs sections, ou les cellules ont des tailles différentes, vous avez besoin de remplacer plus de méthodes. Le même principe s'applique ici: Vous avez besoin de compenser indexPath, la section et de la ligne avant de déléguer à super.
Aussi garder à l'esprit que le indexPath paramètre des méthodes comme l' didSelectRowAtIndexPath:
sera différent pour la même cellule, en fonction de l'état (c'est à dire le nombre de cellules masquées). Donc c'est probablement une bonne idée de toujours de compenser tout indexPath paramètre et de travailler avec ces valeurs.
2. Animer le changement
Comme Gareth déjà dit, vous obtenez les grands pépins si vous animez les modifications à l'aide de reloadSections:withRowAnimation:
méthode.
J'ai découvert que si vous appelez reloadData:
immédiatement après, l'animation est beaucoup améliorée (seuls les petits problèmes de la gauche). Le tableau s'affiche correctement après l'animation.
Donc, ce que je fais:
- (void)changeState
{
// Change state so cells are hidden/unhidden
...
// Reload all sections
NSIndexSet* reloadSet = [NSIndexSetindexSetWithIndexesInRange:NSMakeRange(0, [self numberOfSectionsInTableView:tableView])];
[tableView reloadSections:reloadSet withRowAnimation:UITableViewRowAnimationAutomatic];
[tableView reloadData];
}
Je suis venu avec une solution de rechange qui se cache en réalité de sections et de ne pas les supprimer. J'ai essayé @henning77 de l'approche, mais j'ai continué à courir dans des problèmes quand j'ai changé le nombre de sections de la statique UITableView. Cette méthode a très bien fonctionné pour moi, mais je suis principalement en essayant de cacher des sections au lieu de lignes. Je suis à la suppression de certaines lignes à la volée avec succès, mais il est beaucoup messier, j'ai donc essayé de groupe de choses dans les articles que j'ai besoin de montrer ou de cacher. Voici un exemple de la façon dont je me cache sections:
J'ai d'abord déclarer un NSMutableArray propriété
@property (nonatomic, strong) NSMutableArray *hiddenSections;
Dans le viewDidLoad (ou après que vous avez demandé à vos données) vous pouvez ajouter des sections que vous souhaitez masquer dans le tableau.
- (void)viewDidLoad
{
hiddenSections = [NSMutableArray new];
if(some piece of data is empty){
// Add index of section that should be hidden
[self.hiddenSections addObject:[NSNumber numberWithInt:1]];
}
... add as many sections to the array as needed
[self.tableView reloadData];
}
Puis de mettre en œuvre la suite de la TableView délégué méthodes
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
if([self.hiddenSections containsObject:[NSNumber numberWithInt:section]]){
return nil;
}
return [super tableView:tableView titleForHeaderInSection:section];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if([self.hiddenSections containsObject:[NSNumber numberWithInt:indexPath.section]]){
return 0;
}
return [super tableView:tableView heightForRowAtIndexPath:[self offsetIndexPath:indexPath]];
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
if([self.hiddenSections containsObject:[NSNumber numberWithInt:indexPath.section]]){
[cell setHidden:YES];
}
}
Puis définissez l'en-tête et le pied de la hauteur à 1 pour les sections masquées parce que vous ne pouvez pas régler la hauteur à 0. Cela entraîne un supplément de 2 pixels de l'espace, mais nous pouvons faire pour elle par le réglage de la hauteur du côté visible de l'en-tête.
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
CGFloat height = [super tableView:tableView heightForHeaderInSection:section];
if([self.hiddenSections containsObject:[NSNumber numberWithInt:section]]){
height = 1; // Can't be zero
}
else if([self tableView:tableView titleForHeaderInSection:section] == nil){ // Only adjust if title is nil
// Adjust height for previous hidden sections
CGFloat adjust = 0;
for(int i = (section - 1); i >= 0; i--){
if([self.hiddenSections containsObject:[NSNumber numberWithInt:i]]){
adjust = adjust + 2;
}
else {
break;
}
}
if(adjust > 0)
{
if(height == -1){
height = self.tableView.sectionHeaderHeight;
}
height = height - adjust;
if(height < 1){
height = 1;
}
}
}
return height;
}
-(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
if([self.hiddenSections containsObject:[NSNumber numberWithInt:section]]){
return 1;
}
return [super tableView:tableView heightForFooterInSection:section];
}
Alors, si vous avez des lignes spécifiques pour masquer vous pouvez ajuster la numberOfRowsInSection et les lignes retournées dans cellForRowAtIndexPath. Dans cet exemple, ici j'ai une section qui comporte trois lignes où toutes les trois ont pu être vides et doivent être retirés.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSInteger rows = [super tableView:tableView numberOfRowsInSection:section];
if(self.organization != nil){
if(section == 5){ // Contact
if([self.organization objectForKey:@"Phone"] == [NSNull null]){
rows--;
}
if([self.organization objectForKey:@"Email"] == [NSNull null]){
rows--;
}
if([self.organization objectForKey:@"City"] == [NSNull null]){
rows--;
}
}
}
return rows;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
return [super tableView:tableView cellForRowAtIndexPath:[self offsetIndexPath:indexPath]];
}
Utilisez cette offsetIndexPath pour calculer la indexPath pour les lignes où vous êtes conditionnellement suppression de lignes. Pas nécessaire si vous êtes seulement de masquage de sections
- (NSIndexPath *)offsetIndexPath:(NSIndexPath*)indexPath
{
int row = indexPath.row;
if(self.organization != nil){
if(indexPath.section == 5){
// Adjust row to return based on which rows before are hidden
if(indexPath.row == 0 && [self.organization objectForKey:@"Phone"] == [NSNull null] && [self.organization objectForKey:@"Email"] != [NSNull null]){
row++;
}
else if(indexPath.row == 0 && [self.organization objectForKey:@"Phone"] == [NSNull null] && [self.organization objectForKey:@"Address"] != [NSNull null]){
row = row + 2;
}
else if(indexPath.row == 1 && [self.organization objectForKey:@"Phone"] != [NSNull null] && [self.organization objectForKey:@"Email"] == [NSNull null]){
row++;
}
else if(indexPath.row == 1 && [self.organization objectForKey:@"Phone"] == [NSNull null] && [self.organization objectForKey:@"Email"] != [NSNull null]){
row++;
}
}
}
NSIndexPath *offsetPath = [NSIndexPath indexPathForRow:row inSection:indexPath.section];
return offsetPath;
}
Il ya beaucoup de méthodes pour remplacer, mais ce que j'aime à propos de cette approche est qu'elle est ré-utilisable. Installation de la hiddenSections tableau, ajouter à cela, et il va se cacher la bonne sections. Cacher les lignes, qu'elle est un peu plus difficile, mais possible. On ne peut pas régler la hauteur de l'lignes nous voulons cacher à 0 si nous sommes regroupés à l'aide d'un UITableView parce que les frontières n'obtiendrez pas établie correctement.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.