2010-02-28 11 views
5

Ich habe Probleme beim Animieren eines benutzerdefinierten UITableView-Abschnittsheaders.
Ziel war es, kollabierbare Abschnitte zu erstellen.
Wenn ich beim ersten Mal auf den benutzerdefinierten Header tippe, wie erwartet animiert, jedoch jedes Mal danach ein Duplikat am ursprünglichen Speicherort belässt und animiert einen anderen.UITableView Benutzerdefinierte Abschnittsüberschrift, doppeltes Problem

Bild Beispiel:

alt text http://img35.imageshack.us/img35/4018/screenshot2010022722565.png alt text http://img291.imageshack.us/img291/8287/screenshot2010022723035.png
My Custom Rubrik:

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

meine Animation Methode:

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

Ich bin nicht ganz sicher, was los ist, aber die Instanzen deuten darauf hin, dass ich etwas zu tun habe. Ich habe ein paar Dinge ausprobiert, aber ich kann das nicht herausfinden. Jeder, der dabei helfen würde, wäre großartig!

Bearbeiten: Ich glaube, das Problem ist, dass ReloadSections verursacht die benutzerdefinierte Ansicht Instanz. Ich kann die Ansicht nicht freigeben, da ich sie als Referenz benötige, um das Update für die Animation auszuführen. Irgendwelche Ideen, was ich tun kann, um das zu beheben?

Antwort

8

Lösung gefunden.

Die Tabelle muss vor jeder Änderung neu geladen werden. Auf diese Weise befindet sich die Tabelle im letzten Status, bevor Änderungen vorgenommen werden.

hinzufügen [self.tableView reloadData]; als der erste Eintrag in der Methode "expandSection".

Code:

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

Danke das behebt ein verwandtes Problem, wo ich einen animierten Effekt des Löschens/Einfügens derselben Zeilen erzeugen wollte, wo, ohne zuerst 'reloadData' aufzurufen, nur die Löschungen animiert würden, aber die Einsätze nicht animiert würden. Sehr seltsames Problem war es. – Jeremy

+0

Guter Weg ... + 1 für Sie Mann – Sabby

2

Ich hatte ein ähnliches Problem, das durch die Verwendung dynamische Höhen Zellen verursacht wurde. Ich hatte eine erweiterbare benutzerdefinierte Header-Ansicht und als ich TableView aktualisiert, um die zugehörigen Zeilen des Abschnitts einzufügen und zu entfernen (was bedeutet, dass sie expandierten bzw. zusammenfielen), wurde der Abschnittskopf, der eine Unterklasse von UITableViewHeaderFooterView war, nicht wiederverwendet. Es wurde also im Prinzip eine neue hinzugefügt und über die alte hinzugefügt, was zu überlappenden Ansichten führte. Die Zellenkennung wurde richtig gesetzt, also muss es etwas anderes sein. Als ich tableView.sectionHeaderHeight = UITableViewAutomaticDimension entfernte und func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat implementierte, wurde die Ansicht ordnungsgemäß recycelt und nur eine Header-Ansicht für jeden Abschnitt angezeigt.

Eine andere Lösung, die ich war tatsächlich Arbeit stellte sich heraus, UITableViewCell statt UITableViewHeaderFooterView zu verwenden, und wenn Sie in func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? kehren Sie nur return cell.contenView, dies funktionieren wird, weil das Verfahren eine UIView zurückzukehren erfordert und da die contentView des UITableViewCell a UIView es funktioniert gut. Der Grundgedanke ist, den Wiederverwendungsmechanismus von UITableView durch UITableViewCell zu verwenden und seinen Inhalt nur zurückzugeben, nachdem Sie es konfigurieren.

Fazit. Das Problem ist sehr wahrscheinlich von UITableViewHeaderFooterView verursacht werden, wenn mit Self-Sizing-TableView-Zellen und UITableViewAutomaticDimension anstatt manuell Zelle Höhe verwendet wird.

+0

Lustige Sache, dass ich bereits UITableViewCells für die Header benutzte, nicht mit selbst-Sizing-Zellen, und immer noch hatte ich das Problem hier :) – Gobe

Verwandte Themen