UIActivityIndicatorView nunca anima

Tengo una class PhotoViewController con un @property UIActivityIndicatorView* spinner . FlickrPhotoViewController es una subclass de PhotoViewController que descarga una foto de Flickr y le dice al girador cuándo comenzar y detener la animation. 'updatePhoto' se invoca cada vez que el controller de vista recibe una foto de Flickr:

 - (void)updatePhoto { // Download photo and set it NSLog("updatePhoto called"); if (self.spinner) NSLog(@"Spinner exists in updatePhoto"); dispatch_queue_t downloadQueue = dispatch_queue_create("downloader", NULL); [self.spinner startAnimating]; dispatch_async(downloadQueue, ^{ // Download the photo dispatch_async(dispatch_get_main_queue(), ^{ [self.spinner stopAnimating]; // Set the photo in the UI } }); }); } 

La metodología anterior es exactamente lo que uso para mostrar una rueca en mis controlleres de vista de tabla mientras se descargan los contenidos de la tabla, y siempre funciona allí.

Notarás al comienzo de updatePhoto I imprimir un post si existe UIActivityIndicatorView . Puse una statement similar en awakeFromNib , viewDidLoad y viewWillAppear . Cuando lo ejecuto, este es el resultado exacto que obtengo:

 2013-01-31 21:30:55.211 FlickrExplorer[1878:c07] updatePhoto called 2013-01-31 21:30:55.222 FlickrExplorer[1878:c07] Spinner exists in viewDidLoad 2013-01-31 21:30:55.223 FlickrExplorer[1878:c07] Spinner exists in viewWillAppear 

¿Por qué no existe spinner en awakeFromNib ? Los documentos indican que "cuando un object recibe un post awakeFromNib, se garantiza que todas sus conexiones de salida y acción ya están establecidas". ¿Se puede conectar un IBOutlet sin la existencia del object al que se está conectando? En este caso, ¿se puede conectar el spinner IBOutlet al storyboard sin asignar spinner ?

Más allá de esto, anulé el getter para spinner para que instanciaría si no existiera. Como resultado, la salida de printing ahora se ve así:

 2013-01-31 21:48:45.646 FlickrExplorer[2222:c07] Spinner exists in awakeFromNib 2013-01-31 21:48:45.647 FlickrExplorer[2222:c07] updatePhoto called 2013-01-31 21:48:45.647 FlickrExplorer[2222:c07] Spinner exists in updatePhoto 2013-01-31 21:48:45.649 FlickrExplorer[2222:c07] Spinner exists in viewDidLoad 2013-01-31 21:48:45.650 FlickrExplorer[2222:c07] Spinner exists in viewWillAppear 

Esto es lo que esperaba ver antes. Sin embargo, todavía no recibo ninguna animation.

Posibles problemas que he descartado:

  • La ruleta tiene el mismo color que el background , lo que la hace invisible. En mi proyecto, el background es negro y la ruleta es blanca.
  • Estoy intentando animar el UIActivityIndicatorView mientras que algún método costoso está bloqueando el hilo principal . En mi proyecto, todos los methods de descarga y E / S del sistema de files se invocan en una queue dispatch_async no principal.
  • El IBOutlet del spinner no está conectado . En mi proyecto, he revisado dos veces esta vez. Se puede ver tanto en el storyboard como en el file PhotoViewController.h que está conectado.

Las tres posibilidades se [self.spinner startAnimating]; por el hecho de que poniendo [self.spinner startAnimating]; en viewWillAppear anima con éxito durante todo el process de descarga.

Puede download este proyecto si lo desea. Simplemente vaya a cualquier pantalla que intente mostrar una foto grande y verá que el spinner no aparece. Hay muchos problemas con este proyecto, pero este es el que me estoy enfocando ahora.

Editar 1:

  • Agregué las dependencies faltantes del proyecto en Git, por lo que el proyecto ahora comstackrá para usted

Edición 2 (2 de febrero de 2013):

  • Estoy viendo este problema solo en el iPhone cuando se llama al método updatePhoto debido a que prepareForSegue otro controller de prepareForSegue configurando la foto en FlickrPhotoViewController . ¿Es posible que esto contribuya al problema?

Intente disparar comience a animar un indicador de actividad antes de llamar al método updatePoto como este. Tru llama a esto en lugar de llamar a UpdatePhoto solo a todos:

 [self startAnimatingAndThenUpdatePhoto]; -(void)startAnimatingAndThenUpdatePhoto{ if (self.spinner) NSLog(@"Spinner exists in updatePhoto"); [self.spinner startAnimating]; [self performSelector:@selector(updatePhoto) withObject:nil afterDelay:0.01]; } - (void)updatePhoto { // Download photo and set it NSLog("updatePhoto called"); dispatch_queue_t downloadQueue = dispatch_queue_create("downloader", NULL); dispatch_async(downloadQueue, ^{ // Download the photo dispatch_async(dispatch_get_main_queue(), ^{ [self.spinner stopAnimating]; // Set the photo in the UI } }); }); } 

No es el mejor método en el mundo, pero hará el trabajo