2013-04-16 4 views
15

che sto di fronte a un problema davvero strano sul mio UITableView. Ho alcune celle diverse che voglio visualizzare in una vista tabella simile a un newsfeed.Come è possibile che l'altezza UITableViewCellContentView è diverso da heightForRowAtIndexPath:

e ho un problema con un cellulare dopo il riutilizzo. La cella contiene due immagini, due etichette e una vista con i pulsanti Condividi/Mi piace/Commenti. Sto andando provare a disegnarlo, ma non sono sicuro che sta andando essere abbastanza:

------------------------------------------------- 
|  | __ ____________________________ | 
|  | |_2| |       | | 
|  |  |    3    | | 
|  |  |       | | 
| 1 |  |____________________________| | 
|  |          | 
|  |_______________________________________| 
|  |          | 
|  |     4     | 
|_______|_______________________________________| 
|            | 
|      5      | 
|_______________________________________________| 

1 : objectImage 
2 : subjectImage 
3 : titleLabel 
4 : commentLabel 
5 : actionsView 

E i miei vincoli sono:

"H:|-0-[objectImage(60)]-7-[subjectImage(30)]-7-[titleLabel]-7-|" 
"H:|-0-[objectImage(60)]-0-[commentLabel]-0-|" 
"H:|-0-[actionsView]-0-|" 
"V:|-0-[objectImage(>=35)]-0-[actionsView(44)]-0-|" 
"V:|-7-[subjectImage(30)]" 
"V:|-7-[titleLabel(>=46)]-7-[commentLabel(>=35)]-0-[actionsView(44)]-0-|" 

E ogni volta che viene disegnata la cellula, cambio questo vincolo:

"V:[commentLabel(%0.2f)]" 

Le celle vengono visualizzate perfettamente la prima volta.

Ma, il problema che ho è che a un certo punto, dopo un po 'il riutilizzo (non riesco a riprodurre ogni volta) l'applicazione si blocca a causa di un problema di vincolo. Qui è l'eccezione:

"<NSLayoutConstraint:0x205a75b0 V:[UILabel:0x1ef31430(105)]>", 
"<NSLayoutConstraint:0x1ef34440 V:[UILabel:0x1ef31430]-(0)-[UIView:0x1ef2fe50]>", 
"<NSLayoutConstraint:0x1ef34380 V:[UILabel:0x1ef31250]-(7)-[UILabel:0x1ef31430]>", 
"<NSLayoutConstraint:0x1ef33900 V:|-(7)-[UILabel:0x1ef31250] (Names: '|':UITableViewCellContentView:0x1ef2bf50)>", 
"<NSLayoutConstraint:0x1ef34340 V:[UILabel:0x1ef31250(>=46)]>", 
"<NSLayoutConstraint:0x1efV:[UIView:0x1ef2fe50]-(0)-| (Names: '|':UITableViewCellContentView:0x1ef2bf50)>", 
"<NSLayoutConstraint:0x1ef331d0 V:[UIView:0x1ef2fe50(44)]>", 
"<NSAutoresizingMaskLayoutConstraint:0x1ef36f90 h=--& v=--& V:[UITableViewCellContentView:0x1ef2bf50(147)]>" 


Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x1ef34380 V:[UILabel:0x1ef31250]-(7)-[UILabel:0x1ef31430]> 

Il problema è che il vincolo [UITableViewCellContentView: 0x1ef2bf50 (147)] non è giusto.

Che è strano è che il heightForRowAtIndexPath: restituisce il valore corretto, che è 217.

E quello che non capisco è che l'altezza del UITableViewCell è corretta!

(lldb) po 0x1ef2bf50 
$0 = 519225168 <UITableViewCellContentView: 0x1ef2bf50; frame = (0 0; 320 147); gestureRecognizers = <NSArray: 0x1ef30a20>; layer = <CALayer: 0x1ef2a3d0>> 
(lldb) po [0x1ef2bf50 superview] 
$1 = 0x1ef30e40 <NewsSubjectCommentCell: 0x1ef30e40; baseClass = UITableViewCell; frame = (0 1055; 320 217); hidden = YES; autoresize = W; layer = <CALayer: 0x1ef25e10>> 

Quindi io non capisco come è possibile che il vincolo di altezza UITableViewCellContentView è 147. E 'l'altezza di un'altra cella dello stesso tipo, ma dovrebbe essere cambiato a 209, giusto?

Quindi, se avete una visione chiara su come questo può accadere (forse ho fatto qualcosa di sbagliato), sarei felice.

Grazie,

+0

Hai trovato una soluzione? Sto avendo lo stesso identico problema. –

+0

No, la soluzione (cattiva) che ho usato era aggiungere 1 all'altezza della cella in heightForRowAtIndexPath: funzione –

+0

http://stackoverflow.com/questions/12610783/auto-layout-still-required-after-executing-layoutsubviews- with-uitableviewcel/39136021 # 39136021 – qingqinghebiancao

risposta

2

È necessario spegnere il ridimensionamento automatico di conversione per la vista che contiene i vincoli se si aggiungono i vostri vincoli con codice o linguaggio visivo:

[self.someView setTranslatesAutoresizingMaskIntoConstraints:NO]; 

Ciò impedisce che il vincolo [UITableViewCellContentView:0x1ef2bf50(147)] dalla fase di creazione .

+0

La vista che contiene i miei vincoli è la mia UITableViewCell personalizzata. Ho già provato quello che stai suggerendo, ma quando lo faccio, ho l'errore "Assertion failure in - [NewsSubjectCommentCell layoutSublayersOfLayer:],/SourceCache/UIKit_Sim/UIKit-2380.17/UIView.m:5776". A proposito, se qualcuno potesse dirmi come ottenere il messaggio di asserzione (in modo che io sappia dove cercare esattamente il debug), mi piacerebbe. Ho cercato per mesi ... –

+1

Prova a chiamare questo metodo sulla superview del tuo UITableViewCell. Forse è meglio chiedere informazioni sul fallimento/messaggio di asserzione in una domanda a parte, per tenerlo pulito. – Whakkee

+0

Non puoi. Devi fare questo swizzle per disabilitare la trasformazione della maschera autoresizing in vincoli su una cella di visualizzazione tabella: http://stackoverflow.com/a/12941256/180445 Questo risolverà l'errore di asserzione. Questa è stata la mia soluzione definitiva per l'OP. –

7

Si potrebbe provare a impostare i (/) alcune altezze con una priorità più bassa (per esempio @ 900). Ho avuto un problema simile (il mio UITableViewCellContentView era troppo piccolo e i vincoli non potevano essere soddisfatti). Dopo aver abbassato la priorità della mia altezza "sbagliata", mi sono accontentato delle altezze previste.

+2

Questo ha funzionato per me. Modifica dei limiti o impostazione di UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth no. – giampaolo

+0

Anche questo ha funzionato per me. Ho aggiunto un vincolo di altezza e l'ho impostato su 900 e voilà. –

0

In cellForRowAtIndexPath voi richiesta di una cella dal Tableview. La cella che si otterrà sarà una cella appena creata (con dimensione 320,44) o una cella che è stata rimossa dalla coda e inviato il messaggio prepareForReuse (con qualsiasi dimensione avesse in precedenza). Quando si applica il codice NSLayoutConstraints a contentView, vengono risolti prima dello la cella si adatta allo spazio tableview fornito. Questo non ha senso, ma è sicuramente la conclusione delle mie osservazioni.

Quindi, nel mio caso stavo ottenendo nuove celle con 44 altezza, ma uno dei miei vincoli era per un'altezza fissa di 48. Questo stava lanciando eccezioni costantemente e facendo il debug un dolore. Tutto quello che ho fatto per far sparire le eccezioni è stato quello di impostare il frame della cella all'altezza corretta (e la larghezza suppongo che si verifichino problemi sulla dimensione orizzontale) mentre lo stavo preparando in cellForRowAtIndexPath.

UITableViewCell *cell = [tableview dequeueReusableCellWithIdentifier:CellIdentifier]; 
if(cell==nil) 
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; 
// If the cell is new its frame will be (0,0,320,44) 
cell.frame = CGRectMake(0,0,tableview.frame.size.width,calculatedHeightRequiredForLayout); 
[cell.contentView addConstraints:constraints]; 

La cellula stessa ridimensionerà automaticamente alle dimensioni corrette prima di visualizzare in Tableview in modo da non causare problemi, ma i vostri vincoli di layout verrà applicato senza 'bisogno di essere rotto' da iOS .. .

15

ho trovato la risposta qui: Auto layout constraints issue on iOS7 in UITableViewCell

Non ci resta che impostare l'AutoresizingMask del contentView per UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth e ... problema risolto!

+2

Stavo ricevendo gli avvertimenti "Impossibile soddisfare contemporaneamente i vincoli" quando si tenta di seguire le istruzioni qui: http://stackoverflow.com/a/18746930/528620. Impostando '[self.contentView setAutoresizingMask: UIViewAutoresizingFlexibleHeight]' risolto. Grazie! – ninjudd

+0

Grazie! Sei un salvatore. Stavo impazzendo con il "Incapace di soddisfare simultaneamente i vincoli". – lm2s