2010-03-19 26 views
7

Ho un UITableViewCell personalizzato che contiene diversi UIButtons. La posizione del frame di ciascun pulsante è relativa alla larghezza della cella. Ho impostato autoresizingMask = UIViewAutoresizingFlexibleWidth in modo che regolerà correttamente la larghezza della cella e le posizioni dei pulsanti quando l'applicazione inizia con il dispositivo in modalità orizzontale o verticale.Ruota un UITableViewCell personalizzato

Il problema è quando il dispositivo viene ruotato da una modalità all'altra, i pulsanti non regolano le posizioni perché UITableViewCell è riutilizzabile. In altre parole, la cella non viene inizializzata in base alla nuova larghezza di UITalbeView poiché la funzione della cella initWithStyle viene chiamata prima che il dispositivo venga ruotato e non venga richiamato dopo la rotazione del dispositivo. Eventuali suggerimenti?

+0

Finisce la soluzione è molto più semplice. Ha solo bisogno di impostare self.contentView.autoresizingMask = UIViewAutoresizingFlexibleWidth; self.contentView.autoresizesSubviews = YES; NON funziona impostando self.autoresizingMask. –

+0

Ho lo stesso problema di te e stavo pensando di usare tag cella specifici per ogni caso di orientamento da quando questa idea mi è venuta dopo aver pensato un po '. Utilizzando self.contentView.autoresizesSubviews = YES non funziona dalla mia parte. – user255607

+0

Finalmente ho usato un altro trucco. – user255607

risposta

7

Dopo aver trascorso ore di ricerca (compresi i post in questo sito), non sono riuscito a trovare alcuna soluzione. Ma una lampadina si accende all'improvviso. La soluzione è molto semplice. Rileva solo se l'orientamento del dispositivo è orizzontale o verticale e definisci ReusableCellIdentifier con un nome diverso per ciascuno.

static NSString*Identifier; 

if ([UIDevice currentDevice].orientation!=UIDeviceOrientationLandscapeLeft && [UIDevice currentDevice].orientation!=UIDeviceOrientationLandscapeRight) { 
       Identifier= @"aCell_portrait"; 
      } 
      else Identifier= @"DocumentOptionIdentifier_Landscape"; 


    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:Identifier]; 
+1

Non funziona per le celle personalizzate ... –

6

La risposta precedente presenta un problema grave. Dovresti usare [UIApplication sharedApplication] .statusBarOrientation invece di [UIDevice currebtDevice] .orientation perché l'orientamento del dispositivo non ha nulla a che fare con l'orientamento dell'interfaccia - L'orientamento del dispositivo è la rotazione fisica basata sull'accelerometro.

+0

Grazie per aver informato sulla seconda opzione. In effetti, entrambi possono funzionare. Vedi http://stackoverflow.com/questions/2738734/get-current-orientation-of-ipad –

+2

Mi dispiace, non hai ragione.L'orientamento del dispositivo ha 6 opzioni diverse, mentre l'orientamento dell'interfaccia ha 4. Se il tuo dispositivo è appoggiato sul tavolo, l'orientamento del dispositivo riporterà "Faccia in su", che non ha nulla di comune con l'orientamento dell'interfaccia corrente. – Hrissan

+0

Hrissan, grazie per la correzione. –

1

È necessario correggere la larghezza della cornice della cella (supponendo che l'altezza sia la stessa in modalità verticale e orizzontale) nel metodo cellForRowAtIndexPath. Questo è ciò che funziona qui. Ho usato per creare un TableViewCell personalizzato con IB ed è sempre inizializzato per una larghezza di 320 px di ritratto. Con la definizione del frame funziona come previsto, anche se la cella viene "riutilizzata" dalla coda.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
... 
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier]; 
if (cell == nil) { 
    // create cell here... 
} 

// Adjust cell frame width to be equal to tableview frame width 
cell.frame = CGRectMake(0, 0, tableView.frame.size.width, cell.frame.size.height); 
... 
} 
13

Poiché UITableViewCell è anche un UIView, è possibile sovrascrivere il metodo setFrame. Ogni volta che ruota la vista tabella, questo metodo verrà chiamato per tutte le celle.

-(void)setFrame:(CGRect)frame 
{ 
    [super setFrame:frame]; 

    //Do your rotation stuffs here :) 
} 
0

Ho avuto un problema simile e questo post mi ha aiutato. Nel mio caso ho una classe personalizzata dichiarata in un file separato, e in questo file ho il seguente codice nel layoutSubviews:

//PORTRAIT CELL 
if ([UIDevice currentDevice].orientation!=UIDeviceOrientationLandscapeLeft && 
    [UIDevice currentDevice].orientation!=UIDeviceOrientationLandscapeRight) 
{ 
    //build the custom content views for portrait mode here 
} 
else 
{ 
    //build the custom content views for landscape mode here 
} 

Poi a mio controller di vista ho appena implemento willAnimateRotationToInterfaceOrientation: e inviare il messaggio reloadData al mio tavolo vista.

Con questo non devo toccare il metodo cellForRow.

+1

utilizzando il layoutSubviews non è necessario utilizzare il reloadData, ed è meglio se non lo si utilizza, perché se si è in modalità di edizione con il pulsante Elimina visualizzato e ruotato, il pulsante Elimina scomparirà a causa del reloadData – jcesarmobile

2

La risposta barrata funziona come un fascino nelle vecchie versioni di iOS. Per iOS 6.0 ho usato il prossimo codice:

static NSString *Identifier; 
if (self.interfaceOrientation==UIInterfaceOrientationPortrait) { 
    [email protected]"aCell_portrait"; 
} 
else { 
    [email protected]"DocumentOptionIdentifier_Landscape"; 
} 

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:Identifier]; 
Problemi correlati