2010-03-22 13 views
22

Tengo un UITableView agrupado donde no se pueden mostrar todas las secciones a la vez, la tabla es impulsada por algunos datos que no todos los registros pueden tener. Mi problema es que los registros que no tienen ciertas secciones aparecen como espacios en blanco en la tabla (ver foto)UITableView agrupado muestra el espacio en blanco cuando la sección está vacía

alt text http://img220.imageshack.us/img220/5633/screenshot20100322at228.png

No hay pies de página/cabeceras. ¿Algo que me haya perdido?

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
// Return the number of rows in the section. 
return [self getRowCount:section]; 
} 


// Customize the appearance of table view cells. 
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 

static NSString *CellIdentifier = @"Cell"; 

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
if (cell == nil) { 
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; 
} 

cell.textLabel.text = [NSString stringWithFormat:@"section: %d row: %d",indexPath.section,indexPath.row]; 
// Configure the cell... 

return cell; 
} 

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 

    float height = 0.0; 

    if([self getRowCount:indexPath.section] != 0){ 
     height = kDefaultRowHeight; 
    } 

    return height; 

} 

Respuesta

6

En la imagen anterior, es su numberOfSectionsInTableView: método que devuelve un valor de 5? ¿Y luego su método getRowCount: (llamado desde numberOfRowsInSection:) devuelve un valor de 0 para esas secciones "faltantes" (por ejemplo, 1, 3 y 4)?

Si no desea espacios intermedios, la solución más probable es declarar únicamente el número de secciones que desea que sean visibles. En su ejemplo anterior, solo desea devolver el valor de 3 desde numberOfSectionsInTableView:.

0

Creo que con las vistas de tabla de sección, cada sección debe existir, y cada sección tiene espacio de búfer para un encabezado y un pie de página, independientemente de si pone texto en ellos. Lo que debe hacer es eliminar las secciones que no se están utilizando. En el ejemplo, tendría que quitar la sección 1, 3 y 4. Esto significaría:

sección "0" es == 0 indexPath.section

sección "2" se indexPath.section == 1

"la sección 5" es indexPath.section == 2

Si el código de esta manera, los encabezados y pies de página será eliminado porque se elimina la célula nula.

Esta no es la codificación adecuada, por supuesto, pero quería darte una idea de la teología. Espero que esto ayude.

38

Tengo una situación similar y mi modelo de datos realmente funciona mejor si puedo dejar secciones vacías.

Su problema se puede resolver si establece self.tableView.sectionHeaderHeight = 0; y self.tableView.sectionFooterHeight = 0; en su controlador de tabla de visión. Estos deben ser 0 debido a que los métodos de delegado de alguna manera ignoran un valor de retorno de 0. Entonces usted tiene que reemplazar algunos de los métodos de delegado:

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { 
    if (section==0) 
     return sectionGapHeight; 
    if ([self tableView:tableView numberOfRowsInSection:section]==0) { 
     return 0; 
    } 
    return sectionGapHeight; 
} 
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { 
    if (section==[self numberOfSectionsInTableView:tableView]-1) { 
     return sectionGapHeight; 
    } 
    return 0; 
} 
- (UIView *)sectionFiller { 
    static UILabel *emptyLabel = nil; 
    if (!emptyLabel) { 
     emptyLabel = [[UILabel alloc] initWithFrame:CGRectZero]; 
     emptyLabel.backgroundColor = [UIColor clearColor]; 
    } 
    return emptyLabel; 
} 
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { 
    return [self sectionFiller]; 
} 
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section { 
    return [self sectionFiller]; 
} 

Este código también hará que la brecha entre las secciones de la misma altura que la brecha antes de la primera sección y la brecha debajo de la última. En mi opinión, eso se ve mejor que el valor predeterminado, donde la brecha entre ellos es dos veces mayor que en la parte superior e inferior.

+0

Niza, gracias por el trabajo de investigación! –

+3

El método menos intrusivo que he encontrado hasta ahora es devolver 1 para heightForHeaderInSection y heightForFooterInSection 'if ([self tableView: tableView numberOfRowsInSection: section] == 0)' y devolver una vista con tamaño cero para 'viewForHeaderInSection' /' viewForFooterInSection 'si el recuento de filas es 0. –

+1

¡Gracias! ¡Gracias! Freaking Apple. Sería realmente bueno si documentaran cosas como el hecho de que devolver 0 para las alturas en el delegado no anula el espaciado estándar. Hay demasiados casos sutiles de API que Apple no documenta. – smparkes

4

Esta solución se basa en la solución user362178.Pero mantiene las etiquetas de las secciones intactas:

Definir algún lugar en la parte superior de su código:

#define HEIGHT_FOR_HEADER_AND_FOOTER 50 

Añadir a la vista de carga hizo:

self.tableView.sectionHeaderHeight = 0; 
self.tableView.sectionFooterHeight = 0; 

Añadir estos métodos:

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section 
{ 
    // Needed because if this does not return a value, the header label of the section will 
    // be at the top of the screen. 
    if (section == 0) 
    { 
     return HEIGHT_FOR_HEADER_AND_FOOTER; 
    } 

    if ([self tableView:tableView numberOfRowsInSection:section] == 0) 
    { 
     return 0; 
    } 
    else 
    { 
     return HEIGHT_FOR_HEADER_AND_FOOTER; 
    } 
} 

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section 
{ 
    // if last section 
    if (section == [self numberOfSectionsInTableView:tableView] - 1) 
    { 
     return HEIGHT_FOR_HEADER_AND_FOOTER; 
    } 

    return 0; 
} 
17

Aquí está la solución que funcionó para mí

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { 
    switch (section) { 
     case 1: case 3: case 5: return 20.0f; break; 
     default: return 0.01f; // for some reason 0 is not accepted - give something :) 
    } 
} 

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { 
    switch (section) { 
     case 1: case 3: case 5: return 20.0f; break; 
     default: return 0.01f; // for some reason 0 is not accepted - give something :) 
    } 
} 
+1

Lo leí y pensé "no hay forma de que simplemente no le guste 0.0f". Pero lo comprobé y desde iOS6, este sigue siendo el caso. –

+0

Incluso en iOS 8, 0 no es aceptado, pero 0.01f es :-) –

0

La clave es establecer la vista de tabla sectionHeaderHeight y sectionFooterHeight en cero.

Usted puede hacer esto ya sea en viewDidLoad, o en el tiempo de ejecución definidos por el usuario Atributos sección en su guión gráfico/xib. Por alguna razón, en la pestaña Inspector de Tamaño, no puede establecer la altura del encabezado o pie de página debajo de 1.

Descubrí que una vez que hice esto, no tuve que anular ningún otro método de delegado de una manera especial. Simplemente devuelvo 0 desde numberOfRowsInSection y nil desde titleForHeaderInSection para las secciones que están vacías, y no ocupan espacio en mi vista de tabla.

Las secciones que sí tienen títulos reciben automáticamente el tamaño adecuado de encabezado, y la parte superior de la vista de tabla aún tiene el espacio en blanco predeterminado.

1

que tenían el mismo problema en iOS 7 y finalmente resolvieron este revisar la altura de las secciones de encabezado y pie de página, como Ramesh dijo:

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { 
if ([[self.tableView objectAtIndex:section] count] == 0) 
    return 0.01f; 
else 
    return 30.f; 

}

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { 
return 0.01f; 

}

Es curioso, pero si establece 0.f como la altura, las secciones se muestran con un tamaño predeterminado y se mueve hacia abajo en las otras secciones.

1

Aquí es la solución más elegante que he encontrado sobre la base de todas las respuestas aquí, además de this answer:

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

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

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { 
    if ([self tableView: tableView numberOfRowsInSection: section] == 0) { 
     return 0.01f;; 
    } 

    return UITableViewAutomaticDimension; 
} 

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { 
    if ([self tableView: tableView numberOfRowsInSection: section] == 0) { 
     return 0.01f;; 
    } 

    return UITableViewAutomaticDimension; 
} 
Cuestiones relacionadas