2009-12-12 17 views
11

Esta es la primera vez que hago una pregunta aquí, pero debo decir que este sitio me ha sido de gran ayuda en los últimos meses (iphone-dev- sabio), y te agradezco por eso.UITableView: bloqueo al agregar una vista de pie de página de secciones en la sección vacía

Sin embargo, no encontré ninguna solución para este problema que tengo: Tengo un UITableView con 2 secciones, y no hay filas cuando la aplicación se inicia por primera vez. El usuario puede completar las secciones más tarde como lo desee (el contenido no es relevante aquí). El UITableView se ve bien cuando se llena con filas, pero se ve bastante feo cuando no hay ninguno (las dos secciones de encabezado están pegadas juntas sin espacio en blanco entre ellas). Es por eso que me gustaría agregar una buena vista "Sin fila" en el medio cuando no hay fila.

que utilizan viewForFooterInSection:

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

if(section == 0) 
{ 
    if([firstSectionArray count] == 0) 
     return 44; 
    else 
     return 0; 
} 

return 0; 

} 

- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section{ 

    if(section == 0) 
    { 
     UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(200, 10, 50, 44)]; 
     label.backgroundColor = [UIColor clearColor]; 
     label.textColor = [UIColor colorWithWhite:0.6 alpha:1.0]; 
     label.textAlignment = UITextAlignmentCenter; 
     label.lineBreakMode = UILineBreakModeWordWrap; 
     label.numberOfLines = 0; 
     label.text = @"No row"; 
     return [label autorelease]; 
    } 

    return nil; 
} 

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 
    return 2; 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
    if(section == 0) 
    { 
     return [firstSectionArray count]; 
    } 
    return [secondSectionArray count]; 
} 

Esto funciona muy bien: la opinión de pie de página sólo aparece cuando no hay ninguna fila en la sección 0. Pero mis aplicación se bloquea cuando entro en modo de edición y elimina la última fila en la sección 0:

error de aserción en - [UIViewAnimation initWithView: indexPath: endRect: endAlpha: startFraction: endFraction: curva: animateFromCurrentPosition: shouldDeleteAfterAnimation: edición:] terminación de aplicación debido a excepción no detectada 'NSInterna lInconsistencyException ', razón:' La fracción de detención de animación de celda debe ser mayor que la fracción de inicio '

Esto no ocurre cuando hay varias filas en la sección 0. Solo ocurre cuando solo queda una fila.

Aquí está el código para el modo de edición:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { 
    // If row is deleted, remove it from the list. 
    if (editingStyle == UITableViewCellEditingStyleDelete) { 
     // Find the book at the deleted row, and remove from application delegate's array. 

     if(indexPath.section == 0) 
     { [firstSectionArray removeObjectAtIndex:indexPath.row]; } 
     else 
     { [secondSectionArray removeObjectAtIndex:indexPath.row]; } 

     // Animate the deletion from the table. 
     [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] 
          withRowAnimation:UITableViewRowAnimationBottom]; 


     [tableView reloadData]; 

    } 
} 

¿Alguien tiene alguna idea de por qué está sucediendo esto? Gracias

Respuesta

9

Parece que lo que sucede es que internamente el código de Apple UITableView está asumiendo que cuando se elimina una fila, la primera sección de la vista se hacen más cortos. Al hacer que el pie de página del encabezado de la sección de repente sea más alto para compensar la última fila, parece que lo está confundiendo.

dos ideas para que usted pueda probar:

1. trate de hacer la sección de pie opcional un pixel o dos más pequeña que la celda de tabla que va a desaparecer, por lo que el código de animación llega a hacer un píxel o dos de animación

2. en lugar de eliminar la única fila de la tabla, cuando no hay filas de datos "reales" dejar que la mesa todavía tiene numberOfRowsInSection de retorno 1 y hacer una célula falsa "sin datos" en lugar de utilizando un pie de tabla para el caso "sin datos".

Este es uno de esos casos en los que simplemente tiene que aceptar que Apple ha escrito la mitad de su programa y debe ajustarse a algunas elecciones que su coautor haya realizado, le gusten o no.

+1

¡Eres mi héroe! ¡Hacer que la celda "sin datos" 2 píxeles más pequeña lo hiciera funcionar! Muchas gracias! (y digo, ya había pensado en la segunda solución pero no pude hacerlo funcionar) Todavía tengo un pequeño problema: el fondo de la tabla de visión es blanco ahora cuando no hay fila en la sección 0. me gustó más cuando estaba lleno de celdas vacías (ver imagen aquí: http://yfrog.com/izuitableviewproblemp). ¿Algún consejo? Gracias de nuevo David, has hecho mi día! – nmondollot

+0

no hay grandes ideas allí, tal vez vale la pena una pregunta por separado. –

+0

bien, eso es lo que hice. Gracias – nmondollot

5
  • maquillaje sección vacía
  • cabecera de la tabla uso en esta sección en lugar de pie de página en la primera sección
- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { 
    if (section != OTHER_SECTION_INDEX) { 
     return nil; 
    } 
    //your code here 
} 

- (CGFloat) tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section 
{ 
    if (section != OTHER_SECTION_INDEX) { 
     return 0; 
    } 
    //your code 
} 
+0

¿Qué se supone que es "OTHER_SECTION_INDEX"? – LightningStryk

+0

mi ejemplo cambiando utilizando footer_view en header_view - por lo que debe agregar una sección vacía a continuación para usar header_view. en este caso OTHER_SECTION_INDEX == 0 y header_view estará en la sección 1 – comonitos

+0

No funciona para mí. –

1

que no debería ser necesario llamar tanto deleteRowsAtIndexPaths:withAnimation: y en reloadData tableView.

el problema que está viendo es el problema que veo manifestarse en la llamada al deleteRowsAtIndexPaths:withAnimation:, y por lo tanto para usted, nunca llega a reloadData de todos modos.

una solución más simple para tener que crear nuevas celdas, administrarlas, ocuparse de todos los lugares donde se tiene que tratar una celda diferente, es usar reloadSections:withAnimation: cuando se trata de una sección que va de 0 a 1 fila o de 1 a 0 filas

es decir, sustituir las siguientes líneas de código:

 if(indexPath.section == 0) 
     { [firstSectionArray removeObjectAtIndex:indexPath.row]; } 
     else 
     { [secondSectionArray removeObjectAtIndex:indexPath.row]; } 

     [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] 
         withRowAnimation:UITableViewRowAnimationBottom]; 

con la siguiente

 BOOL useReloadSection; 
     if (indexPath.section == 0) 
     { 
      [firstSectionArray removeObjectAtIndex:indexPath.row]; 
      useReloadSection = 0 == firstSectionArray.count; 
     } 
     else 
     { 
      [secondSectionArray removeObjectAtIndex:indexPath.row]; 
      useReloadSection = 0 == secondSectionArray.count; 
     } 

     if (useReloadSection) 
      [tableView reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] 
        withRowAnimation:UITableViewRowAnimationBottom]; 
     else 
      [tableView deleteRowsAtIndexPaths:@[indexPath] 
          withRowAnimation:UITableViewRowAnimationBottom]; 
+0

¡Gracias! ¡Gran respuesta! – FunkyKat

1

que estaba experimentando el mismo accidente, parece que se trata de un bug in the OS.

Mi caso de uso específico se refiere a una UITableView con secciones expandibles o que se pueden colapsar. Necesito separadores de sección (para esto utilicé el pie de página de sección) pero no divisores de fila (no puedo usar simplemente el separador de celda).

No pude resolver el problema ajustando la altura del pie de página de la sección. Pero cambiar al uso de un encabezado de sección hizo el truco, el error/bloqueo ya no se produce.

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section 
{ 
    CGRect frame = (CGRect){0, 0, self.view.bounds.size.width, 1}; 
    UIView *view = [[UIView alloc] initWithFrame:frame]; 
    view.backgroundColor = [UIColor commentReplyBackground]; 

    return view; 
} 

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section 
{ 
    return 1.0f; 
} 
0

Para aquellos que todavía necesitan la sección de pie de página, también puede intentar cambiar el estilo TableView a UITableViewStyleGrouped. Esto parece eludir el problema. Para obtener la misma apariencia visual, solo tiene que configurar todos sus otros pies de página y encabezados en CGFLOAT_MIN.

Cuestiones relacionadas