Pregunta

Tengo problemas para animar un encabezado de sección UITableView personalizado.
El objetivo era crear secciones plegables.
Cuando toco el encabezado personalizado la primera vez, se anima como se esperaba, sin embargo, cada vez posterior deja un duplicado en la ubicación original y anima otro.

Ejemplo de imagen:

alt text alt text
Mi encabezado personalizado:

- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { 
       UIView* customView = [[[UIView alloc]initWithFrame:CGRectMake(10.0, 0.0, 300.0, 44.0)]autorelease];
       customView.backgroundColor = [UIColor lightGrayColor];

       UILabel * headerLabel = [[[UILabel alloc] initWithFrame:CGRectZero] autorelease];
            headerLabel.backgroundColor = [UIColor clearColor];
            headerLabel.opaque = NO;
            headerLabel.textColor = [UIColor darkGrayColor];
            headerLabel.font = [UIFont boldSystemFontOfSize:16];
            headerLabel.frame = CGRectMake(10, 7, 260.0, 44.0);
            headerLabel.textAlignment = UITextAlignmentCenter;
            NSDictionary *dictionary = [self.data objectAtIndex:section];
            headerLabel.text = [dictionary objectForKey:@"Title"];

            [customView addSubview:headerLabel];


            // add button to right corner of section
        UIButton* headerButton = [[UIButton alloc] initWithFrame:CGRectMake(10, 0, 320, 44)];
            headerButton.center = CGPointMake( 160.0, 22.0);
            headerButton.backgroundColor = [UIColor clearColor];
            headerButton.tag = section;
            [headerButton   addTarget:self action:@selector(expandSection:) forControlEvents:UIControlEventTouchUpInside];

            [customView addSubview:headerButton];

            return customView;
}

Mi método de animación:

- (void) expandSection:(id)sender {

    if (expandedSection == [sender tag]) {
        expandedSection = -1;
        [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:[sender tag]] withRowAnimation:UITableViewRowAnimationNone];
    }else if (expandedSection == -1){
        expandedSection = [sender tag];
        [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:[sender tag]] withRowAnimation:UITableViewRowAnimationNone];
    }else{
        [self.tableView beginUpdates];  
        [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:expandedSection] withRowAnimation:UITableViewRowAnimationNone];
        expandedSection = [sender tag];
        [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:[sender tag]] withRowAnimation:UITableViewRowAnimationNone];
        [self.tableView endUpdates]; 

    }
    //[self.tableView reloadData];
}

No estoy exactamente seguro de qué está pasando, pero los casos sugieren que necesito solucionar algo.He intentado algunas cosas pero no puedo resolver esto.¡Cualquier persona que ayude con esto sería genial!

Editar:Creo que el problema es que reloadSections está provocando que se cree una instancia de la vista personalizada.No puedo liberar la vista porque la necesito como referencia para realizar la actualización de la animación.¿Alguna idea sobre lo que puedo hacer para solucionar este problema?

¿Fue útil?

Solución

solución encontrada.

La tabla necesita ser recargado antes de cada cambio. De esta manera la tabla se encuentra en el último estado antes de hacer cualquier cambio.

add [Self.tableView reloadData]; como la entrada puño en el método de "expandSection".

CÓDIGO:

- (void) expandSection:(id)sender {

  [self.tableView reloadData];

    if (expandedSection == [sender tag]) {
        expandedSection = -1;
        [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:[sender tag]] withRowAnimation:UITableViewRowAnimationNone];
    }else if (expandedSection == -1){
        expandedSection = [sender tag];
        [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:[sender tag]] withRowAnimation:UITableViewRowAnimationNone];
    }else{
        [self.tableView beginUpdates];  
        [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:expandedSection] withRowAnimation:UITableViewRowAnimationNone];
        expandedSection = [sender tag];
        [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:[sender tag]] withRowAnimation:UITableViewRowAnimationNone];
        [self.tableView endUpdates]; 

    }
    //[self.tableView reloadData];
}

Otros consejos

I tenía un problema similar que fue causado por el uso de células de altura dinámica. Tenía una vista encabezado personalizado expandible y cuando estaba actualizando tableView insertar y quitar las filas asociadas de la sección (lo que significa que se estaban expandiendo, respectivamente colapso), el encabezado de sección, que fue una subclase de UITableViewHeaderFooterView no se recicló. Así que, básicamente uno nuevo se asigna y se añadió durante la anterior resulta en la superposición de puntos de vista. La célula se estableció identificador propiamente debe haber sido algo más. Cuando quité tableView.sectionHeaderHeight = UITableViewAutomaticDimension e implementé func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat la vista quedó adecuadamente reciclado y sólo una vista de encabezado se muestra para cada sección.

Otra solución que resultó en realidad el trabajo era utilizar UITableViewCell en lugar de UITableViewHeaderFooterView y cuando regrese en func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? que acaba de return cell.contenView, esto funciona porque el método requiere para devolver un UIView y desde el contentView del UITableViewCell es un UIView funciona muy bien. La idea detrás es utilizar el mecanismo de reciclaje de UITableView través UITableViewCell y simplemente devolver su contenido después de configurar la misma.

Conclusión. El problema es muy posible que es causada por UITableViewHeaderFooterView cuando se utiliza con auto calibrado células tableView y UITableViewAutomaticDimension en lugar de calcular manualmente altura de la celda.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top