2015-02-16 19 views
5

Ich arbeite an einer einfachen Anwendung und jetzt bin ich konzentriert auf die Erweiterung von UITableViewCell nach dem Benutzer tippen Sie auf diese Zelle. Es ist iOS 8-App so ich gesetzt haben:iOS erweitern UITableViewCell auf Klick mit AutoLayout

self.tableVIew.rowHeight = UITableViewAutomaticDimension 
self.tableVIew.estimatedRowHeight = 50 

Zelle Einschränkungen wie folgt aussehen:

enter image description here

Wenn diese Funktion Benutzer Abgriffzelle heißt:

func extend() { 
     self.contentView.removeConstraint(self.bottomConstraint) 

     let additionalView = UIView() 
     additionalView.setTranslatesAutoresizingMaskIntoConstraints(false) 
     additionalView.backgroundColor = UIColor.orangeColor() 
     self.contentView.addSubview(additionalView) 
     self.contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:[additionalView(50)]-5-|", options: nil, metrics: nil, views: ["additionalView" : additionalView])) 
     self.contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-5-[additionalView(100)][email protected]|", options: nil, metrics: nil, views: ["additionalView" : additionalView])) 
    } 

self.bottomConstraint ist costraint zwischen grünem Kreis unten und Zelle contentView unten.

Die Frage ist: Warum diese Lösung nur funktioniert, wenn Priorität in Zwang gesetzt:

V:|-5-[additionalView(100)][email protected]| 

?

Ohne ausdrückliche Priorität habe ich Fehler:

(
    "<NSLayoutConstraint:0x7a63f7a0 'UIView-Encapsulated-Layout-Height' V:[UITableViewCellContentView:0x7a737840(60)]>", 
    "<NSLayoutConstraint:0x7a644f40 V:|-(5)-[UIView:0x7a63f2a0] (Names: '|':UITableViewCellContentView:0x7a737840)>", 
    "<NSLayoutConstraint:0x7a644fb0 V:[UIView:0x7a63f2a0(100)]>", 
    "<NSLayoutConstraint:0x7a644f70 V:[UIView:0x7a63f2a0]-(5)-| (Names: '|':UITableViewCellContentView:0x7a737840)>" 
) 

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x7a644f70 V:[UIView:0x7a63f2a0]-(5)-| (Names: '|':UITableViewCellContentView:0x7a737840)> 
+0

Meine Vermutung ist, dass Ihre aktuelle Zellenhöhe 60 und neue Höhe 110 ist, so dass es eine der Einschränkung brechen muss, um es wachsen zu lassen, Standardpriorität ist 1000, 3 gleiche Priorität Einschränkungen müssen gebrochen werden. – gabbler

+0

Höhe der Zelle sollte nicht dynamisch basierend auf Einschränkungen der Inhaltsansicht berechnet werden? – MichalMoskala

+0

Ja, aber additionalView hat eine Höhe von 100, oder? – gabbler

Antwort

0

'UIView-Encapsulated-Layout-Height' ist die Einschränkung für die Zeilenhöhe nach der Tabellenansicht System erstellt hat errechnet, was es sein sollte. Das einfache Ändern der Integritätsbedingung reicht nicht aus, um eine Neuberechnung zu erzwingen.

Dies ist kein neues unerwartetes Verhalten; Während Effekte manchmal dadurch erzielt werden konnten, dass die Zellen ihre Tabellengröße nicht überschreiten durften, sollte der Tabellenansichtsdatenquellen-Delegat die "offizielle" Zeilenhöhe bereitstellen.

Apples Beispielprojekt Table View Animations and Gestures ist illustrativ. Es wurde nicht für Self-Sizing-Zellen von iOS 8 aktualisiert, aber es ist trotzdem einen Blick wert. In der APLTableViewController.m ist der TableViewController der Delegate für die Pitch-Geste der Zelle, weil sie die Höhe anpassen muss. Seine handlePinch: Anrufe updateForPinchScale: atIndexPath:, die die Erweiterung wie Sie möchten.

Der Tabellenansicht-Controller versucht nicht, die Zeilenhöhe direkt zu ändern. Zuerst legt es sein eigenes benutzerdefiniertes Datenquellenobjekt (AbschnittInfo) fest, um einen aktualisierten Wert für die Zeilenhöhe [sectionInfo replaceObjectInRowHeightsAtIndex:indexPath.row withObject:@(newHeight)]; bereitzustellen. Dann funktioniert die Tabelle View-Controller die folgenden:

BOOL animationsEnabled = [UIView areAnimationsEnabled]; 
[UIView setAnimationsEnabled:NO]; 
[self.tableView beginUpdates]; 
[self.tableView endUpdates]; 
[UIView setAnimationsEnabled:animationsEnabled]; 

alle UIView Animationen ausschalten, weil diese eine Prise ist, so sollte es sofort ohne jerkyness ändern. Da Sie nur eine einmalige Änderung wünschen, sollten Sie mit verschiedenen Animationseinstellungen experimentieren, um den gewünschten Effekt zu erzielen.

Der Schlüssel ist das Paar beginUpdates/endUpdates Aufrufe, die das System scheinbar die Zeilenhöhen neu berechnet. Es ist möglich, dass mit den neuen Self-Sizing-Zellen für iOS die Constraints einfach geändert und diese Methoden aufgerufen werden. versuchen Sie könnten auch reloadRowsAtIndexPaths:withRowAnimation:UITableViewRowAnimationNone

+0

Ich beginUpdates/EndUpdates wie dieser Aufruf: 'func Tableview (Tableview: UITableView, DidSelectRowAtIndexPath indexPath: NSIndexPath) { \t \t \t \t lassen cell = tableView.cellForRowAtIndexPath (indexPath) als TableViewCell \t \t \t \t cell.extend() \t \t tableView.beginUpdates() \t \t tableView.endUpdates() \t} ' und Layout ist korrekt, aber ich bekomme Fehler, wie im ersten Beitrag beschrieben. – MichalMoskala

-2

Satz die Höhe Priorität eines Ihrer Ansichten zu 999 statt 1000

2

ich gemacht habe, eine Demo sandwichartig, dass Sie das genaue Verhalten gibt, wie Sie wollen. Hier ist der Link: https://github.com/rushisangani/TableViewCellExpand

Bitte setzen Sie Einschränkung Ihrer erweitern/reduzieren Ansichten wie in Demo beschrieben.

+0

Danke dafür. Ich weiß, dass ich die Priorität auf 999 setzen kann und es wird funktionieren, aber meiner Meinung nach ist es ein Hack. – MichalMoskala

+0

@MichalMoskala Einstellung eine Priorität zu 999 ist nicht hacken! – iOSEnthusiatic

+0

@iOSENThusiatic Great bro .. !!! viel gelernt von Ihrem einfachen Trick ... _/\\ _ – Akshay

Verwandte Themen