2010-11-05 18 views
17

Tengo un elemento UI de círculo giratorio que se actualiza con un NSTimer. También tengo un UIScrollView que 'bloquearía' el círculo giratorio mientras se desplaza. Eso era de esperar, porque el temporizador y la vista de desplazamiento eran ambos en el mismo hilo.Mis elementos de IU personalizados no se actualizan mientras se desplaza UIScrollView

Así que puse el temporizador en un hilo separado que básicamente funciona muy bien! Puedo ver que funciona porque los NSLogs siguen llegando incluso mientras se desplaza.

¡Pero mi problema es que mi círculo giratorio todavía se detiene al desplazarse! Sospecho que el redibujado se detiene hasta la próxima iteración del ciclo de ejecución del hilo principal (?). Entonces, incluso si su ángulo cambia todo el tiempo, es posible que no se vuelva a dibujar ...

¿Alguna idea de lo que puedo hacer? ¡Gracias!

Respuesta

42

Mientras se desplaza, el ciclo de ejecución del hilo principal está en UITrackingRunLoopMode. Entonces, lo que debe hacer es programar su temporizador en ese modo (posiblemente además del modo predeterminado). Creo NSRunLoopCommonModes incluye tanto los modos de seguimiento de eventos por defecto y, por lo que sólo puede hacer esto:

NSTimer *timer = [NSTimer timerWithTimeInterval:0.42 target:foo selector:@selector(doSomething) userInfo:nil repeats:YES]; 
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; 

Por cierto, usted debe hacer todo esto en el hilo principal. No es necesario generar un hilo de fondo (a menos que cada invocación de temporizador vaya a hacer un procesamiento largo).

+0

+1, funciona muy bien para mí. – pt2ph8

+0

Tienes razón, NSRunLoopCommonModes es el modo correcto para esto, ¡gracias! Me deshice del hilo de fondo y el temporizador se dispara ahora, incluso durante el desplazamiento.Pero mi problema todavía está allí, no se vuelve a dibujar. – Sebastian

+0

¿Qué estás haciendo para desencadenar el redibujado? Creo que un 'setNeedsDisplay' hará el truco. Tal vez deberías publicar tu método de temporizador. –

0

Tiene la razón que UIScrollView no actualiza su vista de contenido durante el desplazamiento.

Probablemente su mejor apuesta, y esto es algo así como un truco, es mostrar su vista animada por separado (tal vez dentro de una vista de marco, para obtener el recorte libre) y usar las devoluciones de llamadas delegadas de la vista de desplazamiento para encontrar saca la posición actual del rollo y coloca tu animación en consecuencia.

NOTA: esta sugerencia es un truco! No se trata de las mejores prácticas y, ciertamente, es contrario al código simple y mantenible sin efectos secundarios. Sin embargo, es la única forma en que puedo pensar para obtener la pantalla que desea.

Otra táctica: reconsidere la importancia de mostrar los contenidos animados de una vista desplazable mientras se desplaza.

+0

No, ¡el círculo de giro animado NO es parte del contenido de la vista de desplazamiento! Lo siento, tal vez no estaba claro en eso. – Sebastian

3

UIScrollView no solo bloquea NSTimers, sino que bloquea todo el hilo principal. Y los objetos UIKit solo deben accederse en el hilo principal (y, a menudo, son limitados de maneras impredecibles si intenta eludir esa restricción), que probablemente sea la razón, incluso si tiene un reloj que viene de un hilo externo, usted No puedo publicar actualizaciones.

Es un poco esquivo, pero ¿hay alguna manera de que su animación se pueda lograr con CoreAnimation? Las cosas vinculadas a eso continúan funcionando independientemente de lo que esté sucediendo en el hilo principal.

+0

Bueno, el temporizador no está bloqueado en absoluto. Lo tengo funcionando en el hilo principal en NSRunLoopCommonModes ahora y se dispara incluso durante el desplazamiento. Pero mi punto de vista no se vuelve a dibujar, al menos no a través del mecanismo setNeedsDisplay/display de UIView. Los documentos dicen: 'Todos los objetos UIView marcados como que necesitan visualización se vuelven a mostrar automáticamente cuando la aplicación regresa al ciclo de ejecución'. – Sebastian

+0

CA es una gran idea, lo intentaré! – Sebastian

Cuestiones relacionadas