2010-11-08 1 views
18

Sto usando UIScrollView e un'immagine in esso come paging un'immagine per pagina. Ho un problema durante la rotazione dello iPhoneUIScrollView disabilita lo scorrimento ruotando su iPhone/iPad

Quando ruoto l'iPhone, viene eseguito il comando scrollViewDidScroll (metodo di scorrimento della vista del delegato). A causa di ciò, il mio cercapersone è disturbato e il numero di pagina cambia.

Qual è la soluzione?

+0

avendo lo stesso problema. .., sei riuscito a risolvere il problema? – negersiu

+1

@ Maciulis..Che esattamente mi è stato fatto in quel momento ... ma controllo il codice .. e non sto usando il metodo scrollViewDidScroll e usando scrollViewDidEndDecelerating .. e uso una variabile globale per il numero di pagina corrente .. spero che questo aiuto o dimmi esattamente cosa vuoi –

risposta

13

Ho trovato uno strano comportamento non documentato durante la rotazione di un paging UIScrollView.

Quando la vista a scorrimento è posizionata nell'ultima pagina e l'utente cambia l'orientamento, il sistema operativo scorre indietro di alcuni pixel lo UIScrollView per compensare la differenza tra altezza e larghezza.

Fondamentalmente ho ricevuto le seguenti chiamate per qualsiasi pagina.

willRotateToInterfaceOrientation:duration 
willAnimateRotationToInterfaceOrientation:duration: 
didRotateFromInterfaceOrientation: 

E per l'ultima pagina:

willRotateToInterfaceOrientation:duration 
scrollViewDidScroll: 
willAnimateRotationToInterfaceOrientation:duration: 
didRotateFromInterfaceOrientation: 

Che incasinato con le mie pagine troppo. Il problema è che in willRotate, i limiti non sono stati aggiornati dal sistema operativo ma, e in willAnimate avete i nuovi limiti e in grado di calcolare la nuova dimensione, ma è troppo tardi ...

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { 

    CGSize tempSize = [self.pagingScrollView contentSize]; 
    NSUInteger padding = abs(pagingScrollView.frame.size.width - pagingScrollView.frame.size.height); 
    tempSize.width += padding; 
    [self.pagingScrollView setContentSize:tempSize]; 
    [...] 
} 
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration{ 
    CGSize newSize = ... // Compute new content size based on new orientation 
    [self.pagingScrollView setContentSize:newSize]; 
} 

questo è solo una soluzione alternativa, ma ho speso innumerevoli ore su questo problema e non sono riuscito a trovare una soluzione elegante.

22

Raphaël's answer è un'eccellente descrizione del problema e una soluzione accurata. Ho avuto lo stesso identico problema e ho finito con il fissare un flag scrollingLocked che ho impostato su SÌ (bloccato) prima che inizi la rotazione e NO (sbloccato) quando finisce. Forse un po 'meno hacky che cambiare temporaneamente il contentSize:

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)orientation 
           duration:(NSTimeInterval)duration 
{ 
    self.photoViewer.scrollingLocked = YES; 
} 

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromOrientation 
{ 
    self.photoViewer.scrollingLocked = NO; 
} 

- (void)scrollViewDidScroll:(UIScrollView*)scrollView 
{ 
    if (self.scrollingLocked) 
    { 
     return; 
    } 
    /* do normal scrollViewDidScroll: stuff */ 
} 
+0

+1 per una risposta corretta + più chiara. –

+0

quale componente è il photoViewer? - Perché non è una pergamena, né una vista –

+2

@matheszabi, sta usando un BOOL ivar da tracciare. In alternativa, è possibile utilizzare semplicemente la proprietà incorporata 'scrollEnabled' di' UIScrollView'. A proposito, questo ancora per qualche motivo attiva 'scrollViewDidScroll' quando nell'ultima immagine. – Steven

0

Il mio compito è quello di permettere lo scorrimento del paesaggio. Il design è per il portait. Mi è venuta l'idea di aggiungere una ScrollView ai componenti o in "Incorpora in Scroll View" in Interface Builder. Mi aspettavo che funzionasse, ma no. Sto usando Xcode 4.4, iOS 5.1, (il progetto dell'ufficio ha bisogno del supporto per 4.2), ma il problema è lo stesso.

In Stack Overflow domanda iPhone SDK: UIScrollView does not scroll c'è una riga che risolve un problema.

Altra prova è in Stack Overflow questione iOS - UIScrollView is not working (it doesn't scroll at all - the image stays fixed), e questo mi ha aiutato, in combinazione con altri, ecco la mia portait-to-scorrevole Codice paesaggio:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromOrientation 
{ 
    if(UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation])){ 
     scrollView.contentSize = portaitScrollSize; 
    } 
    else{//statusbar is Landscape 
     scrollView.contentSize = landscapeScrollSize; 
    }  
} 

Lo ScrollView in legato ad un iVar visualizza in Interface Builder. portaitScrollSize e landscapeScrollSize sono variabili private. Sono inizializzati e non cambiano. In my.h File:

IBOutlet UIScrollView *scrollView; 

In my.m File:

CGSize portaitScrollSize, landscapeScrollSize; 

...

portaitScrollSize = CGSizeMake(320,440); 
landscapeScrollSize = CGSizeMake(480,480); 

Spero che aiutare qualcuno per aggiungere una funzionalità di scorrimento + rotazione ad un disegno portait .

Non dimenticare di permettere portait + paesaggio sul componente superiore:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{ 
    return TRUE; 
} 
0

Oltre alla risposta di Raphaël Mor. Se si passa da verticale a orizzontale, il contenuto si riduce e la struttura della pagina si interrompe. Pertanto, al fine di mantenere la struttura della pagina corrente è sufficiente aggiungere la dimensione del contenuto extra per larghezza:

-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{ 
    [self.scrollView setContentSize:CGSizeMake(self.scrollView.contentSize.width + 400, self.scrollView.contentSize.height)]; 
} 

E assicuratevi di impostare la contentSize e offset di nuovo dopo l'orientamento è cambiato:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation 
{ 
    [self.scrollView setContentSize:CGSizeMake(self.scrollView.bounds.size.width *3, self.scrollView.bounds.size.height)]; 
    [self.scrollView setContentOffset:CGPointMake(self.scrollView.bounds.size.width * self.pageControl.currentPage, 0) animated:NO]; 

}