2015-02-16 13 views
5

Sto lavorando su un'applicazione semplice e ora mi concentro sull'espansione di UITableViewCell dopo che l'utente ha toccato quella cella. E 'iOS 8 app così ho impostato:iOS espande UITableViewCell al clic con AutoLayout

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

vincoli cellulari simile a questa:

enter image description here

Se la cella di rubinetto utente questa funzione viene chiamata:

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 è costraint tra il fondo del cerchio verde e il contenuto della cellaVista il fondo.

La domanda è: Perché questa soluzione funziona solo se c'è impostato priorità vincolo:

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

?

Senza priorità esplicita ho ottenuto errori:

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

La mia ipotesi è che l'altezza corrente della cella sia 60 e la nuova altezza sia 110, quindi è necessario interrompere uno dei vincoli per farlo crescere, la priorità predefinita è 1000, 3 i vincoli con priorità uguale devono essere interrotti. – gabbler

+0

L'altezza della cella non deve essere calcolata dinamicamente in base ai vincoli della vista del contenuto? – MichalMoskala

+0

Sì, ma additionalView ha un'altezza 100, non è vero? – gabbler

risposta

0

'UIView-Encapsulated-Layout-Height' è il vincolo per l'altezza della riga creato dopo che il sistema visualizzazione della tabella ha calcolato quello che dovrebbe essere. Cambiare semplicemente il vincolo all'interno non è sufficiente per forzare il ricalcolo.

Questo non è un nuovo comportamento imprevisto; mentre a volte gli effetti possono essere raggiunti lasciando libere le celle dalla loro altezza fornita dalla tabella, il delegato dell'origine dati della vista tabella ha lo scopo di fornire l'altezza della riga "ufficiale".

Il progetto di esempio di Apple Table View Animations and Gestures è illustrativo. Non è stato aggiornato per le auto-dimensionamento delle celle di iOS 8, ma vale la pena dare un'occhiata a prescindere. Nel APLTableViewController.m il tableViewController è il delegato per il gesto di intonazione della cella, poiché deve regolare l'altezza. Il suo numero handlePinch: chiama updateForPinchScale: atIndexPath: che fa l'espansione come vuoi tu.

Il controller Vista tabella non tenta di modificare direttamente l'altezza della riga. Innanzitutto, imposta il proprio oggetto di origine dati personalizzato (chiamato sectionInfo) per fornire un valore aggiornato per l'altezza della riga [sectionInfo replaceObjectInRowHeightsAtIndex:indexPath.row withObject:@(newHeight)]; . Poi la Table View Controller esegue le seguenti operazioni:

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

Spegnendo tutte le animazioni UIView è perché questo è un pizzico, quindi dovrebbe cambiare istantaneamente senza jerkyness. Poiché desideri solo una modifica una tantum, dovresti provare diverse impostazioni di animazione per ottenere l'effetto desiderato.

La chiave è la coppia di chiamate beginUpdates/endUpdates che a quanto pare attiva il sistema per ricalcolare l'altezza delle righe. È possibile che con le nuove celle auto-dimensionanti iOS, semplicemente cambiando i vincoli e chiamando questi metodi potrebbe essere sufficiente; si potrebbe anche provare a sandwich reloadRowsAtIndexPaths:withRowAnimation:UITableViewRowAnimationNone

+0

sto chiamando beginUpdates/endUpdates come questo: 'func tableView (tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { \t \t \t \t diamo cella = tableView.cellForRowAtIndexPath (indexPath) come TableViewCell \t \t \t \t cell.extend() \t \t tableView.beginUpdates() \t \t tableView.endUpdates() \t} ' e il layout è corretto, ma sto ricevendo errori come descritto nel primo post. – MichalMoskala

-2

insieme la priorità altezza di uno dei vostri punti di vista a 999 invece che 1000.

2

ho fatto un demo che ti dà l'esatto comportamento come si desidera. ecco il link: https://github.com/rushisangani/TableViewCellExpand

Si prega di impostare vincolo dei tuoi Espansione/compressione viste come descritto nella demo.

+0

Grazie per questo. So che posso impostare la priorità su 999 e funzionerà, ma a mio parere è un hack. – MichalMoskala

+0

@MichalMoskala che imposta una priorità su 999 non hack! – iOSEnthusiatic

+0

@iOSEnthusiatic Grande fratello .. !!! ho imparato molto dal tuo semplice trucco ... _/\\ _ – Akshay

Problemi correlati