2010-02-28 13 views
5

Ho problemi a animare un'intestazione di sezione UITableView personalizzata.
L'obiettivo era creare sezioni pieghevoli.
Quando tocco l'intestazione personalizzata la prima volta che si anima come previsto, tuttavia, ogni volta dopo, lascia un duplicato nella posizione originale e ne anima un'altra.UITableView Intestazione sezione personalizzata, duplicato problema

Esempio Image:

alt text http://img35.imageshack.us/img35/4018/screenshot2010022722565.png alt text http://img291.imageshack.us/img291/8287/screenshot2010022723035.png
mio header personalizzato:

- (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; 
} 

mio Animazione Metodo:

- (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]; 
} 

Io non sono esattamente sicuro che cosa sta succedendo, ma la le istanze suggeriscono che ho bisogno di dealoc qualcosa. Ho provato alcune cose ma non riesco a capirlo. Qualunque aiuto su questo sarebbe fantastico!

Modifica: Credo che il problema è che reloadSections sta causando l'istanza della vista personalizzata. Non riesco a rilasciare la vista perché ne ho bisogno come riferimento per fare l'aggiornamento per l'animazione. Qualche idea su cosa posso fare per risolvere questo problema?

risposta

8

Soluzione trovata.

La tabella doveva essere ricaricata prima di ogni modifica. In questo modo la tabella è allo stato più recente prima di apportare modifiche.

aggiungi [self.tableView reloadData]; come prima voce nel metodo "expandSection".

CODICE:

- (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]; 
} 
+0

Grazie a questo risolve un problema correlato in cui volevo produrre un effetto animato di eliminazione/inserimento delle stesse righe, dove, senza prima chiamare 'reloadData', avrebbe solo animato le eliminazioni, ma non animato gli inserti. Era un problema molto strano. – Jeremy

+0

Buon modo ... + 1 per te uomo – Sabby

2

Ho avuto un problema simile che è stato causato da utilizzando cellule di altezza dinamici. Avevo una vista di intestazione personalizzata espandibile e quando stavo aggiornando tableView per inserire e rimuovere le righe associate della sezione (nel senso che stavano espandendo, rispettivamente collassando), l'intestazione di sezione che era una sottoclasse di UITableViewHeaderFooterView non era stata riciclata. Quindi in pratica ne è stato assegnato uno nuovo e aggiunto rispetto a quello vecchio con conseguente visualizzazione sovrapposta. L'identificativo della cella è stato impostato correttamente, quindi deve essere stato qualcos'altro. Quando ho rimosso tableView.sectionHeaderHeight = UITableViewAutomaticDimension e implementato func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat, la vista è stata correttamente riciclata e solo una vista di intestazione è stata visualizzata per ciascuna sezione.

Un'altra soluzione che mi si rivelò in realtà il lavoro è stato quello di utilizzare UITableViewCell invece di UITableViewHeaderFooterView e quando si torna in func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? appena return cell.contenView, questo sistema funziona perché il metodo richiede di restituire un UIView e poiché la contentView del UITableViewCell è un UIView funziona perfettamente. L'idea alla base è utilizzare il meccanismo di riciclaggio di UITableView tramite UITableViewCell e restituire il suo contenuto dopo averlo configurato.

Conclusione. È possibile che il problema sia causato da UITableViewHeaderFooterView quando viene utilizzato con celle TableView con ridimensionamento automatico e UITableViewAutomaticDimension anziché calcolare manualmente l'altezza della cella.

+0

Divertente cosa che stavo già usando UITableViewCells per le intestazioni, non usando le celle di auto-dimensionamento, e ancora ho avuto il problema qui :) – Gobe