2009-05-17 17 views
13

NOTA: Agregué mi nueva solución en la respuesta de ACTUALIZACIÓN a continuación.Fade in/out El contenido de UIScrollView como Mobile Safari lo hace en su pestaña

Intento recrear los efectos que vimos en la pestaña de Mobile Safari en iPhone/iPod touch.

Básicamente, es un UIScrollView que contiene 4 UIView reutilizables (actuando como un buffer de anillo), y se desplaza horizontalmente. Al desplazarse, la opacidad de UIView se desvanecerá/desaparece sin problemas con el desplazamiento.

Actualmente, hago todo el trabajo sucio en - (void)scrollViewDidScroll:(UIScrollView *)scrollView. Como obtener contentOffset de UIScrollView, determinar la creación de páginas, calcular el delta entre contentOffset y cada posición de UIView, y decidir/establecer el valor alfa de cada UIView en el momento en que se llamó al scrollViewDidScroll:.

Y funciona, el rendimiento está bien, todo funciona sin problemas, pero el único problema es calcular demasiado.

Me trataron de beginAnimations: y commitAnimations:, pero es inútil en scrollViewDidScroll:, ya que 1) el nuevo valor alfa todavía tiene que ser calcular por mí mismo, y 2) scrollViewDidScroll UIView: mantiene llama al desplazarse, no tiene sentido hacer la animación aquí. ¿Hay alguna forma de reescribir esta parte con Core Animation? Así que no tengo que hacer los cálculos yo mismo sobre el valor alfa de cada UIView, en cambio, puedo dejar trabajos completos para Core Animation.

Respuesta

26

ACTUALIZACIÓN

me ocurrió otra forma para actualizar el valor alfa de cada página. Al crear vista del contenido, uso de MVA a addObserver con contentOffset de UIScrollView:

[self.scrollView addObserver:[self.contentViews objectAtIndex:i] 
        forKeyPath:@"contentOffset" 
        options:NSKeyValueObservingOptionNew 
        context:@selector(updateAlpha:)]; 

Así que cada uno de mis contentViews obtendrá el mensaje cuando contentOffset cambió:

- (void)observeValueForKeyPath:(NSString *)keyPath 
         ofObject:(id)object 
         change:(NSDictionary *)change 
         context:(void *)context { 
    [self performSelector:(SEL)context withObject:change]; 
} 

Y mis contentViews ha de hacer el cálculo y animar por sí mismos cuando se desplaza:

- (void)updateAlpha:(NSDictionary *)change { 
    CGFloat offset = [[change objectForKey:NSKeyValueChangeNewKey] CGPointValue].x; 
    CGFloat origin = [self frame].origin.x; 
    CGFloat delta = fabs(origin - offset); 

    [UIView beginAnimations:@"Fading" context:nil]; 
    if (delta < [self frame].size.width) { 
     self.alpha = 1 - delta/self.frame.size.width*0.7; 
    } else { 
     self.alpha = 0.3; 
    } 
    [UIView commitAnimations]; 
} 

por supuesto, usted tendrá que quitar el observador cuando se quita la vista de contenido de Superview, y agréguelos nuevamente cuando se cree una nueva vista de contenido.

Espero que esta ayuda a los que quieran hacer lo mismo.

+1

Solo estoy encontrando esto ahora, y es genial, ¡gracias por compartir! Una falla: la alfa inicial no está configurada para la vista fuera de la pantalla. Supongo que podría llamar a updateAlpha: explícitamente, pero tal vez sea suficiente para establecer explícitamente contentOffset al inicio. ¿Pensamientos? –

2

Como se habrá dado cuenta de la frecuencia con la que se llama a scrollViewDidScroll: UIScrollView no solo activa y olvida una transición de Core Animation: mueve manualmente los límites según toques, aceleración, etc. No hay una forma directa de cambiar esta.

Sin embargo, si usted está siendo inundado por los eventos de desplazamiento, puede intentar un truco como el siguiente:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView 
{ 
    NSTimeInterval timestamp = [[NSDate date] timeIntervalSince1970]; 
    if (timestamp - _savedTimestamp) < 0.1) 
     return; 
    _savedTimestamp = timestamp; 

    // do the rest of your work here 
} 

H

+0

hatfinch, gracias por la idea. Aunque no es perfecto, aún así puedes ahorrar algo de potencia de la CPU. – digdog

Cuestiones relacionadas