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;
}
Sébastian
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
}
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
}
}
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
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 vuenil
. 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.
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
}
}
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;
}
}
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
[tableView beginUpdates];
deleteRowsAtIndexPaths
avec les chemins indexPath des cellules que vous avez supprimées.reloadSections:
pour recharger cette section. Cela déclenchera l'animation correcte et masquera/glissera/atténuera l'en-tête.[tableView endUpdates];
pour terminer la mise à jour ..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)
}