2010-07-23 6 views
12

Ho un UIScrollView di paging in cui le pagine dell'utente orizzontalmente attraverso le immagini, come Photos.app di Apple. Funziona, ma ora sto cercando di aggiungere il supporto alla rotazione.Pulire le transizioni di autorotazione in una paginazione UIScrollView

Ho la vista rotante OK e sono riuscito a impostare correttamente i frame contentSize, bounds e subviews per adattarli ai diversi orientamenti. Quindi, prima e dopo la rotazione, tutto è OK.

Tuttavia, le transizioni stesse sono scomode. La prima immagine ruota perfettamente, come se l'asse di rotazione si trovasse nel punto morto dell'immagine (cornice dello scrollview). La seconda immagine "oscilla" perché l'asse di rotazione si trova nello stesso punto: il centro della prima immagine. Più mi allontano dalla prima immagine, più veloce è lo "swing".

Probabilmente posso mascherarlo sovrapponendo un UIView opaco prima della rotazione e nascondendolo dopo. Ma questo è un hack. Ci deve essere un modo elegante per farlo ...

risposta

38

Francamente, non so cosa stai facendo, dal momento che non ci hai mostrato molto.

Ma!

Ho creato un progetto di esempio con alcune viste in una vista di scorrimento e funziona correttamente. Sentiti libero di sceglierlo come desideri. Funziona creando 5 viste e aggiungendole alla vista di scorrimento. Quindi, dopo aver configurato queste visualizzazioni per la prima volta, e ogni volta che l'applicazione ruota, chiama il metodo alignSubviews per posizionarle nelle posizioni corrette della pagina e renderle delle stesse dimensioni della vista di scorrimento, mentre aggiorna la vista di scorrimento contentSize . Prima che avvenga la rotazione, tiene traccia di quale pagina è attualmente attiva la vista di scorrimento, quindi la reimposta su quella pagina durante la rotazione (poiché le dimensioni della pagina devono essere modificate).

Download "Rotolling"!

screenshot http://cl.ly/43de79be29c5a03a1775/content

+0

eccellente esempio! Non ho pubblicato alcun codice perché sapevo che quello che avevo avrebbe dovuto essere demolito. La morale della storia è che se mi trovo manualmente ad impostare e resettare i fotogrammi di visualizzazione dappertutto, sto sbagliando. – alexantd

+0

Grande. Funziona appena fuori dalla scatola. Grazie. – Gerd

+4

Grazie per l'ottimo esempio. È necessario eseguire una correzione per il corretto avvio su iOS 6: [window setRootViewController: viewController]; alla domanda: metodo didFinishLaunchingWithOptions. – kaspartus

1

Sembra che tu stia applicando la magia, necessaria per ottenere la versione ruotata sullo schermo nel posto giusto, nel modo sbagliato.

Dato che non hai condiviso alcun codice, quanto segue è solo una congettura. Presumibilmente, applichi una rotazione e una traduzione. È suoni come se steste ruotando il contenuto dello UIScrollView. Riuscire a farlo bene sarà difficile. È difficile dire qualcosa di conclusivo senza codice, ma se hai solo 1 rotazione e 1 traduzione, lo stai facendo nel modo sbagliato. È necessario tradurre la vista corrente nel punto di rotazione, ruotare e tradurre di nuovo. Altrimenti la traduzione farà parte della rotazione (da qui il grande swing).

È consigliabile ruotare lo stesso UIScrollView. Sarà sempre in una posizione definita (vale a dire: lo schermo) con un centro definito. Il contenuto verrà quindi ruotato con esso.

7

osservo queste informazioni aggiuntive per dopo riferimento me stesso. Ho risolto questo problema con l'idea della soluzione di @jtvandes. Tuttavia, nel mio caso, è stato sufficiente con queste implementazioni. Forzare di nuovo il layout ha interrotto il mio punto di vista.

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration 
{ 
    currentPageOffset = [hostingScrollView contentOffset].x/[hostingScrollView bounds].size.width; 
} 
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration 
{ 
    // Layout changed instantly at this time. 
    // So we have to force to set offset instantly by setting animation to NO. 
    [hostingScrollView setContentOffset:CGPointMake([hostingScrollView bounds].size.width * currentPageOffset, 0.0f) animated:NO]; 
} 
1

Una soluzione semplice che funziona bene è quello di registrare notifiche quando la contentSize del UIScrollView viene modificata e quindi aggiornare il contentOffset in quel momento.

nel metodo di caricamento Visualizza Aggiungi questa linea:

[self addObserver:theScrollView forKeyPath:@"contentSize" options:0 context:nil]; 

Nel tuo metodo di scarico vista aggiungi questa linea:

[self removeObserver:self forKeyPath:@"contentSize"]; 

Cattura la notifica:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 
{ 
    theScrollView.contentOffset = page * theScrollView.bounds.width; 
}