UITableView Custom Section-Header, doppelte Ausgabe
-
23-09-2019 - |
Frage
Ich habe Probleme einen benutzerdefinierten UITableView Abschnitt Kopf Animieren.
Ziel war es, zusammenklappbare Abschnitte zu erstellen.
Wenn ich auf dem benutzerdefinierten Header tippen Sie auf das erste Mal, es wie erwartet animiert, aber jedes Mal nach, dass es hinterlässt ein Duplikat in der ursprünglichen Position und belebt ein andere.
Bild Beispiel:
Mein Benutzerdefinierte Kopfzeile:
- (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 Fälle zeigen, dass ich zu dealoc etwas brauchen. Ich habe ein paar Dinge ausprobiert, aber das kann ich nicht herausfinden. Wer Hilfe zu diesem Thema wäre toll!
Edit: Ich glaube, das Problem ist, dass reloadSections verursacht die benutzerdefinierte Ansicht zu Instanz. Ich kann die Ansicht nicht freigeben, weil ich es als Referenz benötigen Sie das Update für die Animation zu tun. Alle Ideen, was ich tun kann, um dieses Problem beheben?
Lösung
Lösung gefunden.
benötigt die Tabelle vor jeder Änderung neu geladen werden. Auf diese Weise ist der Tisch auf dem neuesten Stand, bevor Sie Änderungen vornehmen.
Add [Self.tableView reload]; wie die Faust Eintrag in der "expandSection" -Methode.
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];
}
Andere Tipps
Ich hatte ein ähnliches Problem, das durch die Verwendung dynamischer Höhen Zellen verursacht wurde. Ich hatte eine erweiterbare benutzerdefinierte Header Ansicht und als ich Tableview wurde die Aktualisierung der zugehörigen Zeilen des Abschnitts einzusetzen und zu entfernen (was bedeutet, dass sie den Ausbau bzw. kollabiert), die der Abschnitt Header eine Unterklasse von UITableViewHeaderFooterView
war nicht recycelt. Also im Grunde ein neues Geschäft wurde über die alte zugewiesen und hinzugefügt, was zu überlappenden Ansichten. Die Zellenkennung richtig so eingestellt wurde, muss etwas anderes gewesen sein. Wenn ich tableView.sectionHeaderHeight = UITableViewAutomaticDimension
entfernt und umgesetzt func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat
wurde die Ansicht ordnungsgemäß recycelt und nur eine Kopfsicht wurde für jeden Abschnitt angezeigt.
Eine andere Lösung, dass ich erwies sich tatsächlich war die Arbeit UITableViewCell
zu verwenden, anstatt UITableViewHeaderFooterView
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 ist ein UIView es funktioniert gut. Die Idee dahinter ist, den Recycling-Mechanismus von UITableView durch UITableViewCell zu verwenden und zurück nur ihren Inhalt, nachdem Sie es konfigurieren.
Fazit. Das Problem ist es sehr gut möglich, durch UITableViewHeaderFooterView
verursacht werden, wenn sie mit Selbst Sizing Tableview Zellen und UITableViewAutomaticDimension
statt der manuellen Berechnung Zellenhöhe verwendet wird.