web-dev-qa-db-fra.com

Comment masquer une section dans UITableView?

Certaines sections du tableau ne contiennent aucune donnée et souhaiteraient masquer cette section.

Comment faire ça?

26
Teo Choong Ping

Vous ne pouvez pas "masquer" une section en tant que telle, mais vous pouvez la "supprimer" de la vue tableau à l'aide de la méthode deleteSections:withRowAnimation:. Cela le supprimera de la vue, avec une animation facultative, sans affecter vos données de sauvegarde. (Cependant, vous devez quand même mettre à jour les données pour que la section ne réapparaisse pas.)

Plus d'informations: Référence de la classe UITableView

21
Tim

En fait, vous pouvez "cacher" une section. Si vous souhaitez utiliser un comportement similaire à celui de l'application Contacts intégrée, où les sections sont masquées mais toujours répertoriées dans l'index de droite, vous pouvez procéder comme suit: 

Implémentez le protocole UITableViewDataSource

  • Renvoie tous les noms de section (même cachés) dans - la méthode sectionIndexTitlesForTableView.

  • Pour chaque section vide, retournez nil à partir de la méthode titleForHeaderInSection.

  • Pour chaque section vide, renvoyez 0 pour la méthode numberOfRowsInSection

Je trouve que cela fonctionne mieux que de supprimer des sections, car l'utilisateur dispose d'une navigation d'index cohérente.

52
TJez

Il est vrai que 0 n’est pas une hauteur valide pour les en-têtes et les pieds de page. Cependant, les hauteurs sont les valeurs de CGFloat. Vous pouvez spécifier un très petit nombre (0,1) pour la hauteur des en-têtes et des pieds de section. 

Une sorte de bidouille, mais ça marche.

13
marcus

Je ne suis pas d'accord avec Tim. Nous avons un moyen d'accéder à n'importe quelle section/ligne d'une table à partir de n'importe où dans notre code et de changer sa propriété .hidden (et toutes les autres propriétés).

C'est la façon dont j'utilise habituellement:

NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:2];
[self.SeymourCakesTableView cellForRowAtIndexPath:indexPath].hidden = YES;
5
Deepukjayan

Vous pouvez définir le nombre de lignes de cette section sur 0. Toutefois, une zone vierge laissera une zone visible. 

2
Cocoanut

Vous pouvez également renvoyer le nombre d'enregistrements contenant des données de la méthode numberofSectionsInTableView: Et utiliser une fonction switch(indexPath.section) Dans laquelle vous laissez les enregistrements vides "passer" au commutateur suivant, par exemple:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    switch (indexPath.section) {
        case 0:
            return <header cell>;
            break;

        case 1:
            if(firstRecordHasData){
                return <second cell>;
                break;
            }

        case 2:
            if(secondRecordHasData){
                return <second cell>;
                break;
            }

        case 3:
            return <some other cell>;
            break;

        default:
            return <a regular cell>;
            break;
    }   
}

Je me débattais avec cela pendant un moment parce que je devais laisser de côté des sections au milieu d’une table groupée. J'ai essayé de régler la hauteur des cellules, de l'en-tête et du pied de page sur 0,0, mais cela n'a pas fonctionné. Impossible de supprimer certaines sections à cause des méthodes appelées en fonction de la ligne sélectionnée. Cela allait être un énorme si… autre si… sinon si avec plusieurs appels de sous-programmes… .. Je suis content d'avoir pensé à la bonne vieille méthode de commutation, peut-être que cela vous aidera aussi :-)

2
Maarten Wolzak

Si vous renvoyez 0 pour la hauteur de la section, l'API Apple l'ignorera. Il suffit donc de renvoyer une petite valeur supérieure à 0.

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
  if (section == 0) {
    return 1;
  }

  return 44;
}

Implémentez également la vue pour en-tête et renvoyez nil pour la section que vous ne souhaitez pas afficher.

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
  if (section == 0 && !self.personaCells.count) {
    return nil;
  }

  UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, 44)];
  UILabel *headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(15, 20, headerView.frame.size.width, 20)];
  NSString *headerTitle = @"SAMPLE TITLE";
  headerLabel.text = headerTitle;    
  [headerView addSubview:headerLabel];
  return headerView;
}
1

Vous pouvez définir la hauteur de rangée de section particulière sur 0. En outre, avec l'en-tête de section si vous le souhaitez. La source de données serait toujours là, mais ne se présenterait pas.

Rangées de sections

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.section == 0) {
        if (_shouldHidden) {
            return 0.0;
        }
        else {
            return 55.0;
        }
    }
    else {
        return 55.0;
    }
}
1
ariauakbar

Vous devrez probablement supprimer la section elle-même des données sauvegardant votre table. Je ne pense pas que quoi que ce soit qui vous permet de cacher une section.

1
Simon

En d’autres termes, les sections et les cellules du tableau sont configurées dans Storyboard. Voici mes stratégies pour masquer une section spécifiée en fonction des conditions.

Première étape : implémentez deux func définis dans UITableViewDelegate - heightForRowAt - heightForHeaderInSection

Par exemple, voici les codes Swift:

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat 
{
   // if indexPath contains the specified section AND
   //    the condition for hiding this section is `true`
   //       return CGFloat(0)
   // else 
   //    return super.tableView(tableView, heightForRowAt: indexPath)
}

override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat 
{
   // similar logic to set header height
}

Deuxième étape : définir une fonction pour définir les cellules masquées pour une section spécifique et l'appeler depuis viewWillAppear:

private func setSectionVisible()
{
   /*
   if condition for visible is true
      let index = IndexPath(row:..., section:...)
      let cell = self.tableView.cellForRow(at: index)
      cell.isHiden = true
   */
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    self.setSectionVisible()
}

Si vous devez recharger une table, vous devrez peut-être appeler à nouveau setSectionVisible().

Je pense que cette stratégie peut fonctionner pour les données dynamiques de DataSource. De cette manière, vous pouvez contrôler quand rendre une section spécifique visible ou masquée.

0
David.Chu.ca

Essayez comme ça: -

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    CGFloat headerHeight=10.f;
    if (section==0)
    {
        headerHeight=0.01f;
    }
    else
    {
        headerHeight=50.0f;
    }
    return headerHeight;
}
0
Hussain Shabbir

Pour masquer une section, même au milieu de la vue du tableau, vous aurez besoin de tous les éléments suivants.

#define DEBUG_SECTION 1

#if ! DEBUG_BUILD
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    if (section == DEBUG_SECTION)
        return CGFLOAT_MIN;
    return [super tableView:tableView heightForHeaderInSection:section];
}
//------------------------------------------------------------------------------

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
    if (section == DEBUG_SECTION)
        return CGFLOAT_MIN;
    return [super tableView:tableView heightForFooterInSection:section];
}
//------------------------------------------------------------------------------

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    if (section == DEBUG_SECTION)
        return nil;
    return [super tableView:tableView titleForHeaderInSection:section];
}
//------------------------------------------------------------------------------

- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
{
    if (section == DEBUG_SECTION)
        return nil;
    return [super tableView:tableView titleForFooterInSection:section];
}
//------------------------------------------------------------------------------

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (section == DEBUG_SECTION)
        return 0;
    return [super tableView:tableView numberOfRowsInSection:section];
}
//------------------------------------------------------------------------------
#endif // #if ! DEBUG_BUILD

si vous avez omis titleFor/headerFor ... vous obtiendrez des lignes vides
si vous avez omis heightFor ... le texte de l'en-tête titre/pied de page apparaîtra toujours 

0
Hofi