2014-11-21 14 views
16

Es gibt viele ähnliche Fragen zu Stack Overflow über UITableViewCell Höhe Animation, aber nichts funktioniert für neue iOS8 Auto-Layout-getriebene Tabellenansicht. Mein Problem:Wie kann UITableViewCell mit Auto-Layout animiert werden?

Benutzerdefinierte Zelle:

@property (weak, nonatomic) IBOutlet iCarousel *carouselView; 
@property (weak, nonatomic) IBOutlet UIPageControl *pageControl; 
@property (weak, nonatomic) IBOutlet UIButton *seeAllButton; 
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *carouselHeightConstraint; 

Hinweis carouselHeightConstraint. Dies ist eine Höhenbeschränkung für die Unteransicht der Inhaltsansicht (die einzige Unteransicht).

Höhe wird beispielsweise auf 230.0f eingestellt. Auf den ersten Last sieht es so aus: enter image description here

Dann auf Alles ansehen Aktion I Zelle erweitern wollen, meinen Code:

- (IBAction)seeAllButtonAction:(id)sender { 

    BOOL vertical = !self.carouselCell.carouselView.vertical; 
    self.carouselCell.carouselView.type = vertical ? iCarouselTypeCylinder : iCarouselTypeLinear; 
    self.carouselCell.carouselView.vertical = vertical; 

    [UIView transitionWithView:self.carouselCell.carouselView 
        duration:0.2 
        options:0 
        animations:^{ 

    self.carouselCell.carouselHeightConstraint.constant = vertical ? CGRectGetHeight(self.tableView.frame) : 230; 
    [self.carouselCell setNeedsUpdateConstraints]; 
    [self.carouselCell updateConstraintsIfNeeded]; 
    [self.tableView beginUpdates]; 
    [self.tableView endUpdates]; 

        completion:^(BOOL finished) { 
        }]; 
} 

Wie Sie sehen können, ich versuchen, diese gut zu bedienen alte Lösung:
Can you animate a height change on a UITableViewCell when selected?

Und das Ergebnis:

enter image description here

Meine Zelle schrumpft zu 44.0f Höhe.

Frage:

Warum dies geschieht? Ich erwarte, dass sich meine Zelle sanft mit der Magie von Auto-Layot erweitert.

Hinweis:
Ich möchte dont't -tableView:heightForRowAtIndexPath: verwenden. Es ist Auto-Layout-Ära, oder?

+0

Sie müssen noch 'tableView: heightForRowAtIndexPath:' verwenden. Das ist kein Auto-Layout-Job. – Astoria

+0

@Astoria, sieht Auto-Layout-Job sehr ähnlich. – orkenstein

+0

@orkenstein Ich stimme völlig zu, das sollte jetzt mit Auto-Layout gemacht werden. Ich versuche grundsätzlich dasselbe zu tun: setze Beschränkungen für die contentView der Zelle und erzähle der Tabellenansicht, um die Höhe zu animieren. Allerdings konnte ich es bisher nicht zur Arbeit bringen. Haben Sie eine Lösung für dieses Problem gefunden? – Alex

Antwort

38

Die folgenden für mich gearbeitet:

Zubereitung:

  1. Auf viewDidLoad der Tabellen-Ansicht sagen selbst Sizing Zellen zu verwenden:

    tableView.rowHeight = UITableViewAutomaticDimension; 
    tableView.estimatedRowHeight = 44; // Some average height of your cells 
    
  2. die Einschränkungen hinzufügen als Das würdest du normalerweise tun, aber füge sie zu contentView der Zelle hinzu!

Animate Höhe ändert:

Sagen Sie bitte eine Einschränkung des ändern constant:

myConstraint.constant = newValue; 

... oder Sie hinzufügen/entfernen Einschränkungen.

diese Änderung zu animieren, gehen Sie wie folgt vor:

  1. die content Sagen um die Änderung zu animieren:

    [UIView animateWithDuration: 0.3 animations: ^{ [cell.contentView layoutIfNeeded] }]; // Or self.contentView if you're doing this from your own cell subclass 
    
  2. Dann die Tabellenansicht sagen, mit einer Animation auf die Höhenänderung reagieren

    [tableView beginUpdates]; 
    [tableView endUpdates]; 
    

Die Dauer von 0,3 im ersten Schritt scheint die Dauer zu sein, die UITableView für seine Animationen verwendet, wenn er begin/endUpdates aufruft.

Bonus - Änderung Höhe ohne Animation und ohne die gesamte Tabelle neu zu laden:

Wenn Sie das gleiche wie oben, aber ohne eine Animation tun wollen, dann tun Sie stattdessen:

[cell.contentView layoutIfNeeded]; 
[UIView setAnimationsEnabled: FALSE]; 
[tableView beginUpdates]; 
[tableView endUpdates]; 
[UIView setAnimationsEnabled: TRUE]; 

Zusammenfassung:

// Height changing code here: 
// ... 

if (animate) { 
    [UIView animateWithDuration: 0.3 animations: ^{ [cell.contentView layoutIfNeeded]; }]; 
    [tableView beginUpdates]; 
    [tableView endUpdates]; 
} 
else { 
    [cell.contentView layoutIfNeeded]; 
    [UIView setAnimationsEnabled: FALSE]; 
    [tableView beginUpdates]; 
    [tableView endUpdates]; 
    [UIView setAnimationsEnabled: TRUE]; 
} 

Sie können meine Implementierung einer Zelle überprüfen, die sich ausdehnt, wenn der Benutzer es here (reine Swift & rein automatischen Layout - wirklich den Weg in die Zukunft) auswählt.

+0

In nicht-animierter Version: würde nicht 'reloadRowsAtIndexPaths: withRowAnimation:' mit 'UITableViewRowAnimationNone' in der Tabellenansicht funktionieren? Anstatt Animationen auf 'UIView' und' beginUpdates'/'endUpdates' zu deaktivieren. –

+0

@ MichałCiuba Ich erinnere mich nicht daran, das genau auszuprobieren, aber ich erinnere mich daran zu denken: "Es scheint, dass' reloadRowsAtIndexPaths: withRowAnimation: 'Zellenhöhen nicht neu lädt. Ich denke, ich muss etwas anderes versuchen." wurden für die Animation der Höhe, aber kein sofortiges Update). – Alex

+1

Ja, ich meinte: rufe 'layoutIfNeeded' zuerst auf, um die Höhe der Zelle zu aktualisieren, dann' reloadRowsAtIndexPaths: withRowAnimation: ', um die Tabellenansicht zu aktualisieren. –

1

Ich möchte ein paar Punkte zu Alex Antwort hinzufügen.

Wenn Sie beginUpdates und EndUpdates innerhalb cellForRowAtIndexPath oder willDisplayCell anrufen, wird Ihre Anwendung zum Absturz bringen. Nachdem Sie die Erhöhung Ihrer Zelle animiert haben, möchten Sie vielleicht, dass sie nach dem Scrollen zu Ihrem TableView gleich bleibt. Sie können auch möchten, dass der Rest der Zellen ihre Höhe gleich bleibt. Denken Sie jedoch daran, dass Zellen wiederverwendbar sind, sodass Sie möglicherweise andere Zellen mit größerer Höhe haben.

Als Ergebnis erhalten Sie die Constraint konstanten Innen cellForRowAtIndexPath in Abhängigkeit von der Position festgelegt haben, um es darstellt. Aber wenn Sie danach layoutIfNeeded aufrufen, wird eine Warnung mit Ihren Einschränkungen angezeigt. Ich glaube, dass es versucht, das Zellenlayout zu generieren, bevor seine neue Höhe berechnet wird.

public func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
... 
    myConstraint.constant = itemForCell.value == "x" ? 50 : 20 // stop right here 
    cell.layoutIfNeeded() <- don't do this or some of your constraints will break 
    beginUpdates() <-- if you do this your app will crash 
    endUpdates() <-- same here 
Verwandte Themen