2014-11-20 19 views
5

Ho una cella di visualizzazione tabella personalizzata definita nel file storyboard.Quando il layout è completo per UITableViewCell personalizzato?

enter image description here

Questa cella contiene vista di scorrimento con poche pagine di contenuto e di un indicatore di pagina. Scorri le visualizzazioni, la visualizzazione del contenuto e la cella stessa, tutte definite mediante l'auto-layout. Le visualizzazioni Pagina1/2/3 sono associate per avere la stessa larghezza della vista di scorrimento e il binding del contenitore per avere una larghezza di 3 volte come visualizzazione di scorrimento. In questo modo non sono sicuro che il contenuto sia esattamente dimensionato per mostrare tre pagine di informazioni indipendentemente dalle dimensioni dello schermo.

Ho un codice nella classe di cella personalizzata per aggiornare l'indicatore della pagina quando la vista di scorrimento ha fatto scorrere - questo funziona correttamente.

ho esposto anche il metodo nella classe di cellule per specificare la pagina dall'esterno, e in questo setter sto facendo qualcosa di simile:

- (void)setPage:(NSInteger)page animated:(BOOL)animated 
{ 
    CGFloat pageWidth = self.scrollView.frame.size.width; 
    self.pageControl.currentPage = page; 
    [self.scrollView setContentOffset:CGPointMake(page*pageWidth, 0) animated:animated]; 
} 

Il problema che sto affrontando è molto spesso scorrere frame vista e la dimensione del contenuto non è definita correttamente quando sto chiamando questo setter, quindi l'indicatore di pagina sarà impostato, ma la vista di scorrimento non cambia l'offset del contenuto.

Dove posso trovare un momento in cui l'auto-layout della mia cella è completo e posso garantire che setContentOffset funzionerà? Ho provato a chiamare setPage da cellForIndexPath - che ovviamente non funziona, quindi ho provato a chiamarlo da willDisplayCell - stessa storia - la cella stessa è già strutturata correttamente, ma la vista di scorrimento ha ancora 600px (dallo storyboard) e fallisce.

+0

Stai cercando di visualizzare il contenuto impaginato? –

+0

Sì. Questo è esattamente ciò che sto cercando di fare – sha

risposta

1

Sembra che tu sia impostato su un'implementazione su misura, quindi ecco cosa potrebbe funzionare.

Chiamare il metodo -setPage:animated: prima della visualizzazione della tabella impostare le sue viste secondarie, dando la cellula la possibilità di fare lo stesso, o il layout automatico calci nel non funzionerà a meno a mantenere uno stato in cella (probabilmente solo la pagina numero) e reagire ad una o più delle seguenti opportunità:

  1. attesa fino a quando il metodo dei tuoi incendi UITableViewController -viewDidLayoutSubviews e quindi chiamare -cellForRowAtIndexPath: per ottenere il cellulare. La cella dovrebbe quindi avere una cornice valida.

  2. Ignora -didMoveToSuperview nella UITableViewCell personalizzata. Nel momento in cui questo è chiamato il frame dovrebbe anche essere valido.

Dopo uno di questi punti si poteva controllare lo stato del tuo cellulare personalizzato (che dovrebbe contenere il numero di pagina che deve essere visualizzato) e scorrere fino al punto appropriato. Avrebbe probabilmente senso rifattorizzare il metodo per impostare lo stato (una proprietà intera sulla cella) e disporre di un metodo privato separato che -setPage:animated: e una delle due sovrascritture precedenti potrebbero chiamare per calcolare l'offset e fare lo scorrimento.


Alternativa suggerita:

Si potrebbe tirare fuori questo grazie all'integrazione di un UICollectionView nella cella del contentView. Il tuo UIViewController che attualmente implementa UITableViewDataSource potrebbe anche implementare UICollectionViewDataSource e fornire la vista di raccolta con le sue celle.

Supponendo che le cellule UITableView sono la larghezza e l'altezza dello schermo è possibile configurare la visualizzazione raccolta incorporato per impaginare sostanzialmente orizzontale (dal UICollectionView è una sottoclasse di UIScrollView).

Quando si imposta la visualizzazione collezione utilizzare UICollectionViewFlowLayout come oggetto layout e configurarlo in questo modo:

// Ensure the collection view scrolls horizontally. 
let flowLayout = UICollectionViewFlowLayout(); 
flowLayout.scrollDirection = .Horizontal; 

let collectionView = UICollectionView(frame:tableCellFrame, layout:flowLayout); 

// These are actually UIScrollView properties. 
collectionView.pagingEnabled = true; 
collectionView.bounces = false; 

È quindi posizionare ogni pagina di contenuti in un costume UICollectionViewCell e la vista di raccolta li impaginare per voi . Questo ha il vantaggio di fornire un'API di scorrimento impaginato gratuitamente.

+0

Stai suggerendo di mettere UIPageController all'interno della cella? – sha

+0

No, metti completamente fuori UITableView. –

+0

Questa non è un'opzione. Devo occuparmi di questo all'interno della cella – sha

12

ho finito per fare il seguente:

Nella sottoclasse cella personalizzato aggiunto il layoutSubview implementazione

- (void)layoutSubviews 
{ 
    [super layoutSubviews]; 

    [self.contentView layoutSubviews]; 

    // set proper content offset 
    [self.scrollView setContentOffset:CGPointMake(self.frame.size.width*self.pageControl.currentPage, 0) animated:NO]; 
} 

Senza di me chiamando direttamente layoutSubview sul contentView vista di scorrimento non ha avuto adeguata cornice anche dopo [super layoutSubview] era finito.

Non ho dovuto memorizzare il numero di pagina corrente nella variabile interna, poiché pageControl lo contiene già ed è impostato durante la configurazione delle informazioni sulla cella originale.

Qual è stato interessante anche se - in origine ho aggiunto [self.scrollView layoutSubview] dentro quel metodo e stava funzionando benissimo in iOS 8, ma non ha fatto nulla di buono in iOS7. Ho dovuto salire di un livello a contentView per assicurarmi che funzioni sia in 7 che in 8.

Problemi correlati