2014-09-24 11 views
12

Ho implementato l'altezza delle celle Tableview dinamico automatiche per iOS 8 utilizzandoCome sovrascrivere un metodo in base alla versione iOS del sistema di runtime?

self.tableView.rowHeight = UITableViewAutomaticDimension; 

Per pre-IOS 8, che non supporta altezze automatici cellulari dinamico, ho overrided il metodo heightForRowAtIndexPath.

Questa è una simile a quello che ho fatto: Using Auto Layout in UITableView for dynamic cell layouts & variable row heights

Il problema è di come scrivere codice che utilizza altezza della cella automatica per iOS 8, ma la priorità heightForRowAtIndexPath per le versioni precedenti di iOS. Vorrei il mio metodo heightForRowAtIndexPath personalizzato solo se la versione di iOS è inferiore a 8. Qualche suggerimento su come farlo?

+3

si potrebbe anche prendere in considerazione solo utilizzando una diversa origine dati in iOS 7 e iOS 8. (ovvero un oggetto di una classe diversa) –

+0

@JesseRusak è assolutamente corretto e questa è la pratica consigliata. Creare un cluster di classi per l'origine dati che fornisce l'implementazione concreta appropriata in fase di runtime. – quellish

risposta

19

Una soluzione sarebbe sostituire il metodo respondsToSelector: nel controller di visualizzazione. È necessario restituire NO in iOS 8 quando si verifica il metodo heightForRowAtIndexPath:.

- (BOOL)respondsToSelector:(SEL)selector { 
    static BOOL useSelector; 
    static dispatch_once_t predicate = 0; 
    dispatch_once(&predicate, ^{ 
     useSelector = [[UIDevice currentDevice].systemVersion floatValue] < 8.0 ? YES : NO; 
    }); 

    if (selector == @selector(tableView:heightForRowAtIndexPath:)) { 
     return useSelector; 
    } 

    return [super respondsToSelector:selector]; 
} 

In questo modo, quando la vista della tabella effettuare una chiamata del tipo:

if ([self.delegate respondsToSelector:@selector(tableView:heightForRowAtIndexPath:)]) { 
} 

il codice restituirà NO sotto iOS 8 o versioni successive e YES sotto iOS 7 o versioni precedenti.

+0

Ho aggiunto questo come categoria per 'UITableViewController', quindi non devi aggiungerlo a tutti. Inoltre puoi testare se il selettore è 'tableView: estimateHeightForRowAtIndexPath:', poiché ritengo che non sia necessario per iOS8. – Koen

+0

@Koen È pericoloso eseguire l'override di un metodo in una categoria poiché si tratta di un comportamento non definito. Potrebbe funzionare o no. – rmaddy

+0

Buon punto, rimuoverò la categoria e aggiungerò questo ad ogni 'UITableViewController' – Koen

1

Ho trovato una soluzione semplice. dichiarata questa macro di riconoscere se l'utente ha iOS 8.0 o versione successiva:

#define IS_IOS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) 

Poi, all'interno heightForRowAtIndexPath ho aggiunto il seguente codice:

if (IS_IOS_8_OR_LATER) { 
     self.tableView.rowHeight = UITableViewAutomaticDimension; 
     return self.tableView.rowHeight; 
    } else {//Custom code for ios version earlier than 8.0 

} 

Questo ha risolto il problema

+1

Lo svantaggio di questo approccio è la perdita di molte prestazioni. Poiché la tabella rileva l'implementazione del metodo delegato 'heightForRowAtIndexPath', lo chiama per ogni riga. La mia soluzione ti restituisce il guadagno in termini di prestazioni. – rmaddy

Problemi correlati