406 Stimmen

Können Sie eine Höhenänderung auf eine UITableViewCell animieren, wenn ausgewählt?

Ich benutze eine UITableView in meiner iPhone-App, und ich habe eine Liste von Personen, die zu einer Gruppe gehören. Ich möchte es so, dass, wenn der Benutzer auf eine bestimmte Person klickt (also die Zelle auswählen), die Zelle in der Höhe wächst, um mehrere UI-Steuerelemente für die Bearbeitung der Eigenschaften dieser Person anzuzeigen.

Ist dies möglich?

886voto

Simon Lee Punkte 22274

Ich habe eine WIRKLICH EINFACHE Lösung für dieses Problem als Nebeneffekt einer UITableView Ich habe an..... gearbeitet.

Speichern Sie die Zellenhöhe in einer Variablen, die die ursprüngliche Höhe normalerweise über die tableView: heightForRowAtIndexPath: Wenn Sie dann eine Höhenänderung animieren wollen, ändern Sie einfach den Wert der Variablen und rufen dies auf...

[tableView beginUpdates];
[tableView endUpdates];

Sie werden feststellen, dass es nicht für eine vollständige Nachladung ausreicht, aber für die UITableView um zu wissen, dass die Zellen neu gezeichnet werden müssen, wobei der neue Höhenwert für die Zelle.... übernommen wird, und raten Sie mal? Es ANIMATISIERT die Änderung für Sie. Toll.

Ich habe eine ausführlichere Erklärung und vollständige Codebeispiele in meinem Blog... Animieren UITableView Zelle Höhe ändern

64voto

Mark A. Punkte 1065

Mir gefällt die Antwort von Simon Lee. Ich habe diese Methode noch nicht ausprobiert, aber es sieht so aus, als würde sie die Größe aller Zellen in der Liste ändern. Ich hatte gehofft, dass sich nur die Zelle ändert, die angetippt wird. Ich habe es in etwa so gemacht wie Simon, aber mit einem kleinen Unterschied. Dies wird das Aussehen einer Zelle ändern, wenn sie ausgewählt wird. Und es ist animiert. Nur ein anderer Weg, es zu tun.

Erstellen Sie ein int, um einen Wert für den aktuell ausgewählten Zellindex zu speichern:

int currentSelection;

Dann:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    int row = [indexPath row];
    selectedNumber = row;
    [tableView beginUpdates];
    [tableView endUpdates];
}

Dann:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {

    if ([indexPath row] == currentSelection) {
        return  80;
    }
    else return 40;

}

Ich bin sicher, dass Sie ähnliche Änderungen in tableView:cellForRowAtIndexPath: vornehmen können, um den Typ der Zelle zu ändern oder sogar eine xib-Datei für die Zelle zu laden.

Auf diese Weise beginnt die currentSelection bei 0. Sie müssen Anpassungen vornehmen, wenn Sie nicht möchten, dass die erste Zelle der Liste (bei Index 0) standardmäßig ausgewählt aussieht.

22voto

Joy Punkte 221

Hinzufügen einer Eigenschaft zur Verfolgung der ausgewählten Zelle

@property (nonatomic) int currentSelection;

Setzen Sie ihn auf einen Sentinel-Wert in (zum Beispiel) viewDidLoad , um sicherzustellen, dass die UITableView beginnt in der "normalen" Position

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    //sentinel
    self.currentSelection = -1;
}

En heightForRowAtIndexPath können Sie die gewünschte Höhe für die ausgewählte Zelle festlegen

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    int rowHeight;
    if ([indexPath row] == self.currentSelection) {
        rowHeight = self.newCellHeight;
    } else rowHeight = 57.0f;
    return rowHeight;
}

En didSelectRowAtIndexPath Sie speichern die aktuelle Auswahl und speichern ggf. eine dynamische Höhe

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
        // do things with your cell here

        // set selection
        self.currentSelection = indexPath.row;
        // save height for full text label
        self.newCellHeight = cell.titleLbl.frame.size.height + cell.descriptionLbl.frame.size.height + 10;

        // animate
        [tableView beginUpdates];
        [tableView endUpdates];
    }
}

En didDeselectRowAtIndexPath den Auswahlindex wieder auf den Sentinel-Wert setzen und die Zelle wieder in die normale Form bringen

- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {       
        // do things with your cell here

        // sentinel
        self.currentSelection = -1;

        // animate
        [tableView beginUpdates];
        [tableView endUpdates];
    }
}

17voto

raf Punkte 2429

Anstelle von beginUpdates() / endUpdates() ist der empfohlene Anruf jetzt:

tableView.performBatchUpdates(nil, completion: nil)

Apple sagt in Bezug auf beginUpdates/endUpdates: "Verwenden Sie, wann immer möglich, die Methode performBatchUpdates(_:completion:) anstelle dieser Methode."

Siehe: https://developer.apple.com/documentation/uikit/uitableview/1614908-beginupdates

14voto

lawrence Punkte 9099

ReloadData ist nicht gut, weil es keine Animation gibt...

Das ist es, was ich derzeit versuche:

NSArray* paths = [NSArray arrayWithObject:[NSIndexPath indexPathForRow:0 inSection:0]];
[self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationFade];
[self.tableView deleteRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationFade];
[self.tableView endUpdates];

Es funktioniert fast richtig. Fast. Ich erhöhe die Höhe der Zelle, und manchmal gibt es einen kleinen "Schluckauf" in der Tabellenansicht, wie die Zelle ersetzt wird, als ob einige Scrollen Position in der Tabellenansicht erhalten bleibt, die neue Zelle (die die erste Zelle in der Tabelle ist) endet mit seinem Offset zu hoch, und die scrollview springt, um es neu zu positionieren.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X