objective c - UITableView: ocultar el encabezado de la sección vacía
objective-c ios (7)
Tengo una UITableView, que muestra los gastos de un mes actual (ver captura de pantalla):
Mi problema es con el encabezado de las secciones vacías. ¿Hay alguna forma de ocultarlos? Los datos se cargan de coredata.
este es el código que genera el título del encabezado:
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;
}
sebastian
¿Qué pasa si in - tableView:viewForHeaderInSection:
return nil
si el recuento de secciones es 0.
EDITAR : Puede usar numberOfRowsInSection
para obtener la cantidad de elementos en la sección.
EDITAR : Probablemente deberías devolver nil también en titleForHeaderInSection
si numberOfRowsInSection
es 0.
EDIT : ¿Implementaste el siguiente método?
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
EDITAR : Ejemplo de Swift 3
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
}
Eche un vistazo al método -[UITableViewDelegate tableView:heightForHeaderInSection:]
. Especialmente la nota que acompaña a su documentación:
Antes de iOS 5.0, las vistas de tabla cambiarían automáticamente el tamaño de las alturas de los encabezados a 0 para las secciones donde
tableView:viewForHeaderInSection:
devolvió una vistanil
. En iOS 5.0 y posterior, debe devolver la altura real para cada encabezado de sección en este método.
En mi extraña situación, tengo que regresar:
viewForHeaderInSection -> nil
viewForFooterInSection -> nil (¡no te olvides del pie de página!)
heightForHeaderInSection -> 0.01 (¡no cero!)
heightForFooterInSection -> 0.01
solo en este caso las secciones vacías desaparecen por completo
Esta parece ser la forma correcta, se animará correctamente y funciona limpia ... como Apple pretendía ...
Proporcione la información adecuada al delegado de TableView
Cuando no hay elementos en la sección, devuelve 0.0f en:
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
.. También devuelve nil por:
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
Hacer la eliminación de datos adecuada para tableView
- Llame a
[tableView beginUpdates];
- Elimine los elementos de su dataSource, controlando dónde se eliminaron los elementos.
- Llame a
deleteRowsAtIndexPaths
con indexPaths de las celdas que eliminó. - si su fuente de datos no tiene elementos (aquí terminaría con solo el encabezado). Call
reloadSections:
para volver a cargar esa sección. Esto disparará la animación correcta y ocultará / deslizará / fundirá el encabezado. - Finalmente, llame a
[tableView endUpdates];
para terminar la actualización ..
Sé que esta es una pregunta antigua, pero me gustaría agregar algo más. Prefiero el enfoque de establecer titleHeader
en nil sobre la alteración de heightForHeaderInSection
en 0, ya que puede causar problemas con indexPath
siendo +1 desde donde debería ser debido a que el encabezado aún está allí pero oculto.
Entonces, dicho esto y basándose en la respuesta de DBD, puede establecer el titleForHeaderInSection:
para titleForHeaderInSection:
nulo para las secciones que no tienen filas:
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if ([tableView.dataSource tableView:tableView numberOfRowsInSection:section] == 0) {
return nil;
} else {
// return your normal return
}
}
en 2015 usando iOS 8 y xCode6, lo siguiente funcionó para mí.
/ * Devuelve el título para cada sección si y solo si el recuento de filas para cada sección no es 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;
}
}
tableView:heightForHeaderInSection:
establecer tableView:heightForHeaderInSection:
en 0 para las secciones apropiadas. Esto es algo que cambió bastante recientemente y me metió en un par de lugares. De UITableViewDelegate
dice ...
Antes de iOS 5.0, las vistas de tabla cambiarían automáticamente el tamaño de las alturas de los encabezados a 0 para las secciones donde tableView: viewForHeaderInSection: devolvió una vista nula. En iOS 5.0 y posterior, debe devolver la altura real para cada encabezado de sección en este método.
Entonces tendrás que hacer algo como
- (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
}
}