Pregunta

Tengo un controlador UableViewview que aparece un UIIMagePickerController, el usuario toma una imagen, presiona el botón de uso, Picker descarta para mostrar una spinner de miniatura personalizada mientras se procesa la imagen, luego la hiladora se reemplaza por la miniatura real al final del procesamiento.

Al menos así fue como funcionó en iOS4. Ahora con iOS5, simplemente se sienta allí hasta que esté terminado, y luego todo funciona correctamente. Pero quiero que esa ruleta esté allí para que el usuario sepa que algo está sucediendo, de lo contrario parece que simplemente colgó.

Entonces tengo esto:

- (void) actionSheet: (UIActionSheet *)actionSheet didDismissWithButtonIndex (NSInteger)buttonIndex {
    UIImagePickerController *picker = [[UIImagePickerController alloc] init];
    picker.delegate = self;
    picker.allowsEditing = NO;
    // yada, yada, yada
    [self presentModalViewController:picker animated:YES];
    [picker release];
}

Y luego esto se llama cuando el usuario elige "usar":

- (void) imagePickerController: (UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    [self dismissModalViewControllerAnimated:YES];
    [self performSelectorOnMainThread:@selector(processImage:) withObject:info waitUntilDone:NO];
    animate = true;
}

Y luego se llama a esto para realizar el procesamiento mientras la miniatura está girando:

- (void) processImage:(NSDictionary *)info
{
    UIImage *image = nil;
    NSString* mediaType = [info objectForKey:UIImagePickerControllerMediaType];
    // processing of image
    animate = false;
    [activityImageView stopAnimating];
    [activityImageView release];
    [self.tableView reloadData];
}

Como dije, funcionó perfectamente con iOS4, pero con iOS5, no hay tanta suerte. Entonces, ¿cuál es el trato? El selector de la imagen se descarta eventualmente, entonces, ¿por qué no se descarta de inmediato?

¿Fue útil?

Solución

No estoy seguro de por qué hay una disparidad entre iOS4 & iOS5 en este punto. Pero su descripción de la interfaz de usuario es bastante consistente con el código que ha mostrado. El selector de rendimiento en el hilo principal está haciendo exactamente eso, realizando el selector en el hilo principal, que es el hilo desde el que está llamando. Debido a esta configuración waitUntilDone: a NO no tiene sentido ya que no se envía a otro hilo, simplemente se está ejecutando en orden. Probablemente obtendría los resultados que desea simplemente intercambiar el pedido, así:

[self dismissModalViewControllerAnimated:YES];
animate = true;
[self performSelectorOnMainThread:@selector(processImage:) withObject:info waitUntilDone:NO];

Pero tenga en cuenta que esto sería arriesgado en el mejor de los casos, ya que supongo // processing of image no contiene concurrencia. Prefiero bloques para la concurrencia. Y además de eso me gustan los bloques anidados para que la concurrencia sea fácil de seguir, por ejemplo:

-(void)doSomeStuffInBackground{
    // Prepare for background stuff
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        // Do background stuff
        dispatch_async(dispatch_get_main_queue(), ^{
            // Update UI from results of background stuff
        });
    });
}

Entonces, con eso en mente, sugeriría algo más como esto:

-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
    [self dismissModalViewControllerAnimated:YES];
    [self processImage:info];
}

-(void)processImage:(NSDictionary *)info{
    animate = true;
    UIImage *image = nil;
    NSString* mediaType = [info objectForKey:UIImagePickerControllerMediaType];

    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        // processing of image here on background thread

        dispatch_async(dispatch_get_main_queue(), ^{
            // update UI here on main thread
            animate = false;
            [activityImageView stopAnimating];
            [activityImageView release];
            [self.tableView reloadData];
        });
    });
}

Esto descargaría el trabajo principal en un hilo de fondo para dejar que la interfaz de usuario se mantenga receptiva.

Otros consejos

Tratar de usar

[[picker presentingViewController] dismissViewControllerAnimated:YES completion:nil]; 

en vez de:

[[picker parentViewController] dismissModalViewControllerAnimated: YES];
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top