2013-07-12 9 views
9

Il mio UITableView ha un gruppo di celle riutilizzabili e quando tocco su una di esse, mi porta ad un altro controller di visualizzazione (tramite push segue) che mostra i dettagli di quella cella (diciamo è un oggetto, quindi mostrerebbe dettagli su un oggetto: nome, prezzo, immagine, ecc ...). Quando visualizzo il controller di visualizzazione (toccando il pulsante Indietro), lo UITableView ha uno strano comportamento:Comportamento strano di UITableViewController dopo aver scoccato un controller di visualizzazione

a) se viene fatto scorrere fino in fondo, scorrerà automaticamente verso l'alto (circa 50 punti), lasciando l'ultima cella appena visibile, quindi devo tornare indietro di nuovo. Le mie celle hanno tutte 60 punti per altezza.

b) la barra di scorrimento mostra sempre e quindi scompare, indicando che qualcosa si sta muovendo che UITableView (sebbene se non scorresse verso il basso, il contenuto non si muoverà automaticamente).

Questo succede in più UITableView che ho nella mia app. Non sto forzando un ricaricamento della vista tabella in viewWillAppear, quindi non capisco cosa sta succedendo. Il mio contenuto è statico dopo il caricamento dal server (a meno che l'utente non lo modifichi e quindi venga eseguito il ricaricamento). Ma semplicemente mostrando i dettagli di un oggetto e scoppiando che VC non cambia nulla nella vista tabella.

Modifica: OK, ho capito qual è il problema: sto nascondendo un UIToolbar quando spingo quel seguito. Se lo tengo sempre visibile (che non voglio), mostra ancora le barre di scorrimento che si animano quando scoppiettano nella mia vista tabella ma non scorre la vista tabella se sulle ultime righe.

risposta

2

Sono riuscito a risolvere il primo problema. Sembra che la vista tabella non tenga conto dei 44 punti dello UIToolbar.

Salva l'offset in prepareForSegue: Tableview (salvarlo in una proprietà CGPoint)

self.tableViewScrollOffset = self.tableView.contentOffset; 

Poi, nel viewWillAppear:, controllare se è stato modificato. Se è così, ripristinalo.

if(self.tableView.contentOffset.y != self.tableViewScrollOffset.y) { 
     [self.tableView setContentOffset:self.tableViewScrollOffset]; 
     self.tableViewScrollOffset = CGPointZero; 
    } 
+0

Potresti spiegare più in dettaglio perché questo sta accadendo? O potrebbe qualcuno. – Krtko

+0

Il suo stupefacente ... ha risolto il problema simile ... Il problema è che, ogni volta che si torna indietro da un viewcontroller, l'offset di scorrimento della vista tabella cambia di conseguenza. Quindi è necessario acquisire il valore contentoffset in una proprietà all'interno di prePareForSegue: metodo (ad esempio, prima di navigare) e quindi verificare che nella stessa classe all'interno di viewWillAppear: method. E se viene modificato, imposta il valore della proprietà scrolloffset su zero –

0

Solo un sospetto, hai un ladro scrollToRowAtIndexPath:atScrollPosition:animated in giro?

+0

No, ho cercato il mio intero progetto che in Xcode e senza linee di codice pop-up. – swiftcode

+0

Ho aggiornato il mio problema con alcune informazioni più pertinenti. – swiftcode

7

Aggiungere quanto segue a viewDidLoad.

self.automaticallyAdjustsScrollViewInsets = NO; 

Questo ha risolto il mio problema della visualizzazione della tabella spostandosi verso il basso dopo essere tornati indietro per visualizzare il controller.

3

Questo comportamento è davvero un bug in iOS 8.x.

Tutte le risposte fornite finora non possono realmente risolvere il problema. Il problema è che iOS dimentica (o non) considera le dimensioni delle celle calcolate in precedenza, quando una tabella viene ridisegnata per esempio quando viene spinto la vista.

Un approccio per risolvere questo può essere trovato qui: UITableView layout messing up on push segue and return. (iOS 8, Xcode beta 5, Swift) (quindi questa domanda è anche un duplicato per questo).

Tuttavia, la soluzione a condizione che v'è eccessivo e ci sono certe situazioni perché questo caching mancherà (ad esempio un UIContentSizeCategoryDidChangeNotification non è considerata)

Ma c'è una soluzione molto più semplice, anche se è strano:

Se si utilizza un manuale performSequeWithIdentifier in didSelectRowAtIndexPath, è sufficiente aggiungere un [self.tableView reloadData] poco prima.

Se si sta utilizzando un IB seque dalla cella, è sufficiente aggiungere [self.tableView reloadData] nel codice prepareForSeque.

Il motivo, perché questo risolve il problema è che questo costringerà iOS a stimare nuovamente le celle visibili e quindi non scorre più il contenuto in un'altra posizione. Fortunatamente, tableView reloadData non costa troppo overhead in quanto solo le celle visibili verranno rideterminate.

0

Mi trovavo anche di fronte a questo problema. Sono riuscito a scoprirlo. Il motivo nel mio caso è l'altezza dell'intestazione tableview era il calcolo del testo basato e l'altezza del testo era negativa a causa della quale tableview si stava spostando verso il basso anche se contentinset e scrollinset sono zero.

Questo si verificava solo per la prima volta. La prossima volta sta calcolando correttamente. Una cosa weired che ho trovato è che quando la Classe A (avendo tableview) ha spinto un'altra Classe B da init. Quando viene aperta la tastiera della classe B, viene chiamato viewDidLoad della classe A. e prima che la classe B venga scaricata dal controller di navigazione. Tableview viene ricaricato per la Classe A.

0

L'impostazione di automaticAdjustsScrollViewInsets come suggerito sopra non ha funzionato né ha fatto il caching e l'impostazione di tableViewScrollOffset.

Quindi è venuto fuori con un trucco che ha funzionato come un fascino per me.

La soluzione alternativa era aggiungere un UIView fittizio con altezza di 1 px e larghezza di 320 px e inserirlo tra la "Guida al layout principale" e UITableView. Lo sfondo di questa vista potrebbe essere impostato per cancellare in modo che sia invisibile.

Ora utilizzando gli Autolayout, correggere la Vista fittizia in alto. Ora imposta il vincolo più alto della vista tabella rispetto a Vista fittizia. Scoprì che questo risolveva il problema del disallineamento della tableview.

Schermata della vista fittizia insieme ai vincoli di autolayout forniti per una facile consultazione. La vista fittizia è stata impostata su un'altezza maggiore e un colore di sfondo rosso a scopo illustrativo.

enter image description here

Problemi correlati