web-dev-qa-db-fra.com

UITableView: masquer l'en-tête de la section vide

j'ai un UITableView, qui affiche les dépenses d'un mois en cours (voir capture d'écran):

Mon problème est avec l'en-tête pour les sections vides. y a-t-il un moyen de les cacher? Les données sont chargées à partir de coredata.

c'est le code qui génère le titre de l'en-tête:

TitleForHeader

-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
if ([tableView.dataSource tableView:tableView numberOfRowsInSection:section] == 0) {
    return nil;
} else {

NSDate *today = [NSDate date ];
int todayInt = [dataHandler getDayNumber:today].intValue;

NSDate *date = [NSDate dateWithTimeIntervalSinceNow:(-(todayInt-section-1)*60*60*24)];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:[[NSLocale preferredLanguages] objectAtIndex:0]]];    
[dateFormatter setTimeStyle:NSDateFormatterNoStyle];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
NSString *formattedDateString = [dateFormatter stringFromDate:date];
    return formattedDateString;}

}

ViewForHeader

-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
if ([tableView.dataSource tableView:tableView numberOfRowsInSection:section] == 0) {
    return nil;
} else {

    UIView *headerView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 312, 30)];
    UILabel *title = [[UILabel alloc]initWithFrame:CGRectMake(4, 9, 312, 20)];
    UIView *top = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 312, 5)];
    UIView *bottom = [[UIView alloc]initWithFrame:CGRectMake(0, 5, 312, 1)];

    [top setBackgroundColor:[UIColor lightGrayColor]];
    [bottom setBackgroundColor:[UIColor lightGrayColor]];

    [title setText:[expenseTable.dataSource tableView:tableView titleForHeaderInSection:section]];
    [title setTextColor:[UIColor darkGrayColor]];
    UIFont *fontName = [UIFont fontWithName:@"Cochin-Bold" size:15.0];
    [title setFont:fontName];


    [headerView addSubview:title];
    [headerView addSubview:top];
    [headerView addSubview:bottom];

    return headerView;

}

}

heightForHeader

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {

NSLog(@"Height: %d",[tableView.dataSource tableView:tableView numberOfRowsInSection:section] == 0);
if ([tableView.dataSource tableView:tableView numberOfRowsInSection:section == 0]) {
    return 0;
} else {
    return 30;
}
}

numberOfRowsInSection

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
 {

int rows = 0;
for (Expense* exp in [dataHandler allMonthExpenses]) {
    if ([exp day].intValue == section) {
        rows++;
    }
}

return rows;
}

enter image description here Sébastian

72

Et si dans - tableView:viewForHeaderInSection: toi return nil si le nombre de sections est 0.

EDIT : Vous pouvez utiliser numberOfRowsInSection pour obtenir le nombre d'éléments de la section.

EDIT : Vous devriez probablement renvoyer nil également dans titleForHeaderInSection si numberOfRowsInSection vaut 0.

EDIT : Avez-vous mis en œuvre la méthode suivante?

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

EDIT : Swift exemple

override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    switch section {
    case 0:
        if self.tableView(tableView, numberOfRowsInSection: section) > 0 {
            return "Title example for section 1"
        }
    case 1:
        if self.tableView(tableView, numberOfRowsInSection: section) > 0 {
            return "Title example for section 2"
        }
    default:
        return nil // when return nil no header will be shown
    }
    return nil
}
56
LuisEspinoza

Vous devez définir tableView:heightForHeaderInSection: à 0 pour les sections appropriées. C'est quelque chose qui a changé assez récemment et m'a amené dans quelques endroits. De UITableViewDelegate il est dit ...

Avant iOS 5.0, les vues de table redimensionnaient automatiquement les hauteurs d'en-tête à 0 pour les sections où tableView: viewForHeaderInSection: renvoyait une vue nulle. Dans iOS 5.0 et versions ultérieures, vous devez renvoyer la hauteur réelle pour chaque en-tête de section de cette méthode.

Donc, vous devrez faire quelque chose comme

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    if ([tableView.dataSource tableView:tableView numberOfRowsInSection:section] == 0) {
        return 0;
    } else {
        // whatever height you'd want for a real section header
    }
}
132
DBD

Dans mon étrange situation, je dois rentrer:

viewForHeaderInSection -> nil

viewForFooterInSection -> nil (n'oubliez pas le pied de page!)

heightForHeaderInSection -> .01 (pas zéro!)

heightForFooterInSection -> 0.01

seulement dans ce cas, les sections vides disparaissent complètement

53
djdance

Regardez la méthode -[UITableViewDelegate tableView:heightForHeaderInSection:] . Surtout la note qui accompagne sa documentation:

Avant iOS 5.0, les vues de table redimensionnaient automatiquement les hauteurs d'en-tête à 0 pour les sections où tableView:viewForHeaderInSection: a retourné une vue nil. Dans iOS 5.0 et versions ultérieures, vous devez renvoyer la hauteur réelle pour chaque en-tête de section de cette méthode.

10
Sixten Otto

Je sais que c'est une vieille question, mais j'aimerais ajouter quelque chose. Je préfère l’approche consistant à régler le titleHeader sur nil plutôt que de modifier le heightForHeaderInSection à 0 car cela peut causer des problèmes avec le indexPath étant +1 à partir d’où is devrait être dû à l’en-tête être toujours là mais caché.

Donc, avec cela dit et en s'appuyant sur réponse de DBD vous pouvez définir le titleForHeaderInSection: à nil pour les sections sans lignes comme ceci:

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    if ([tableView.dataSource tableView:tableView numberOfRowsInSection:section] == 0) {
        return nil;
    } else {
        // return your normal return
    }
}
9
gav

En 2015, avec iOS 8 et Xcode 6, les éléments suivants ont fonctionné pour moi:

/* Return the title for each section if and only if the row count for each section is not 0. */

-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{

    if ([tableView.dataSource tableView:tableView numberOfRowsInSection:section] == 0) {
        return nil;
    }else{

    // here you want to return the title or whatever string you want to return for the section you want to display

    return (SomeObject*)someobjectArray[section].title;
    }
}
7
Ronaldoh1

Cela semble être le bon moyen, il s'animera correctement et fonctionnera proprement ... comme Apple destiné ...

Fournissez les informations appropriées au délégué tableView

Si aucun élément dans la section, retourne 0.0f dans:

-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section

.. Également renvoyer nul pour:

-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section

élimine les données appropriées pour tableView

  1. Appel [tableView beginUpdates];
  2. Supprimez les éléments de votre source de données en gardant une trace des endroits où les éléments ont été supprimés.
  3. Appelez deleteRowsAtIndexPaths avec les chemins indexPath des cellules que vous avez supprimées.
  4. si votre source de données ne contient aucun élément (ici, vous vous retrouveriez avec juste l'en-tête). Appel reloadSections: pour recharger cette section. Cela déclenchera l'animation correcte et masquera/glissera/atténuera l'en-tête.
  5. Enfin, appelez [tableView endUpdates]; pour terminer la mise à jour ..
5
Andres Canella

Swift 4.2

Définissez heightForHeaderInSection sur zéro et, si vous avez une vue en coupe personnalisée, définissez-la sur nil pour les sections sans cellules.

func tableView(_ tableView: UITableView,
                   heightForHeaderInSection section: Int) -> CGFloat {
        return height_DefaultSection
    }

func tableView(_ tableView: UITableView,
                   viewForHeaderInSection section: Int) -> UIView? {

        return tableView.dataSource?.tableView(tableView, numberOfRowsInSection: section) == 0 ? nil: headerView(tableView: tableView, section: section)
    }
2
user550088