2012-06-10 16 views
25

Estoy tratando de reproducir la animación suave de una vista de desplazamiento con la paginación habilitada cuando se desplaza a la página siguiente. Parece ser UIViewAnimationCurveEaseInOut, pero necesito tener un botón de "página siguiente" y trigonar el desplazamiento programáticamente.UIScrollview setContentOffset con animación no lineal?

Aquí está mi código:

-(void) scrollToPage:(int)page 
{ 
    UIScrollView *scrollView = contentView; 
    CGPoint offset = CGPointMake(scrollView.bounds.size.width * page, scrollView.contentOffset.y); 
    [scrollView setContentOffset:offset animated: YES];  
    [self pageControlUpdate]; 
} 

-(void) scrollToNextPage 
{ 
    [self scrollToPage:(pageControl.currentPage + 1)]; 
} 

puedo o no reproducir la suavidad de UIViewAnimationCurveEaseInOut, ya sea con setContentOffset, o con scrollRectToVisible ... que pasa a la página siguiente con una animación lineal fea

incluso he intentado animar manualmente:

[UIView animateWithDuration:.5 delay:0 options:UIViewAnimationCurveEaseInOut animations:^{ 
    scrollView.contentOffset = offset; 
} completion:^(BOOL finished) { } ]; 

¿dónde estoy equivocado?

+0

encontré esto: http://developer.apple.com/library/ios/#DOCUMENTATION/WindowsViews/Conceptual/UIScrollView_pg/ScrollingViewContent/ScrollingViewContent.html que confirman lo que vi: 'La setContentOffset: animada: rollos método de las contenido al desplazamiento de contenido especificado. Si el parámetro animado es SÍ, el desplazamiento se animará desde la posición actual a la posición especificada a una velocidad constante. – Diwann

+0

arg. Nadie podría tener alguna pista? – Diwann

+0

Bueno, si 'UIViewAnimationCurveEaseInOut' no funciona, probablemente sea una curva de animación diferente. Es muy posible que Apple use una curva personalizada para esta animación. Usando 'CAPropertyAnimation', puede definir su propia curva personalizada en forma de' CAMediaTimingFunction'. Puede valer la pena jugar con diferentes puntos de control. –

Respuesta

21

Cada vez que haga sus propias animaciones que tienen que pasar NO como animated: parámetro:

- (void)scrollToPage:(int)page 
{ 
    UIScrollView *scrollView = contentView; 
    CGPoint offset = CGPointMake(scrollView.bounds.size.width * page, 
           scrollView.contentOffset.y); 

    [UIView animateWithDuration:.5 
          delay:0 
         options:UIViewAnimationCurveEaseInOut 
        animations:^{ 
         [scrollView setContentOffset:offset animated:NO]; 
        } completion:nil]; 

    [self pageControlUpdate]; 
} 
+0

y por cierto. un tiempo de animación de arreglo se verá extraño en algunos casos. p.ej. solo recorre 2 líneas, también tomará medio segundo. Y en la otra dirección, si tienes una lista muy, muy larga y te desplazas de arriba a abajo, será superrápida en medio segundo. –

+0

Gracias por esta explicación, pero solo me desplazo por un ancho de página completo para que siempre parezca la misma velocidad. Intenté con el parámetro animado: NO pero sigue desplazándose a velocidad fija. También traté de cambiar las animaciones UIViewAnimationCurve, pero se ve igual. Estoy probando la solución personalizada CAPropertyAnimation de Ole. – Diwann

+0

Esto funciona muy bien. Sin embargo, pequeña nitpick, debería ser UIViewAnimationOptionCurveEaseInOut. –

6

Con el uso de las API públicas, no creo que esto es posible en la actualidad. Suponiendo que no necesita interacción del usuario durante el curso de la animación, sería mejor que animara la posición de las subvistas de su UIScrollView (es decir, el contenido de la vista de desplazamiento) y luego ajuste el contentOffset sin animación al finalizar. Usted puede hacerlo de esta manera:

- (void) scrollToPage:(int)page { 
    UIScrollView *scrollView = contentView; 
    scrollView.userInteractionEnabled = NO; 
    CGPoint offset = CGPointMake(scrollView.bounds.size.width * page, scrollView.contentOffset.y); 
    CGFloat delta = offset.x - scrollView.contentOffset.x; 

    __block int animationCount = 0; 
    for (UIView *view in scrollView.subviews) { 
     [UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{ 
      animationCount++; 
      CGRect frame = view.frame; 
      frame.origin.x -= delta; 
      view.frame = frame; 
     } completion:^(BOOL finished) { 
      animationCount--; 
      if (animationCount == 0) { 
       scrollView.contentOffset = offset; 
       for (UIView *view in scrollView.subviews) { 
        CGRect frame = view.frame; 
        frame.origin.x += delta; 
        view.frame = frame; 
       } 
       scrollView.userInteractionEnabled = YES; 
      } 
     }]; 
    } 
} 

puedo confirmar esto funciona como se esperaba, he probado yo mismo.

+0

Sí, es una solución alternativa interesante. Pero sí necesito usar el valor de contentOffset en tiempo real para mover mi vista dentro de la vista de desplazamiento mientras se desplaza, y esta solución no funciona con scrollviewdidscroll. – Diwann

+0

Bueno, sí activa 'scrollViewDidScroll' cuando configuras' contentOffset' al final. Pero puedes extraer cualquier manejo adicional que realices en 'scrollViewDidScroll' y en su lugar usarlo dentro de este método. –

+0

Alternativamente, podría incrustar todas sus subvistas 'UIScrollView' en otra' UIView', que podría subclase y anular 'setFrame:', ya que durante una animación sería esencialmente equivalente a 'scrollViewDidScroll'. –

4
[UIView animateWithDuration:(Animation_Duration) 
          delay:0.0 
         options:UIViewAnimationOptionCurveEaseInOut 
        animations:^{ 
        [scroll setContentOffset:CGPointMake(PointX, PointY) animated:NO]; 
         } 
        completion:^(BOOL finished){}];` 
3

Esta clase salvados absolutamente mi vida:

MOScroll on GitHub.com

Tiene

- (void)setContentOffset:(CGPoint)contentOffset withTimingFunction:(CAMediaTimingFunction *)timingFunction duration:(CFTimeInterval)duration;

Al igual que la API privada pero con todos los métodos públicos y matemáticas.

+0

Enlace de trabajo para MOScroll: https://github.com/plancalculus/MOScrollView – Koen

Cuestiones relacionadas