Pourquoi ne pas ignorermodalviewcontrolleranimated ignorer UIImagePickerController immédiatement sur ios5?

StackOverflow https://stackoverflow.com/questions/8409461

Question

J'ai un utailviewController qui apparaît un UiImagePickerController, l'utilisateur prend une photo, frappe le bouton Utiliser, le sélecteur est de montrer une fileuse à vignettes personnalisée lorsque l'image est en cours de traitement, puis le filateur est remplacé par la vignette réelle à la fin.de traitement.

au moins c'est comme ça que cela a fonctionné dans iOS4.Maintenant, avec iOS5, il suffit de traiter jusqu'à ce qu'il soit fini, puis tout fonctionne correctement.Mais je veux que ce fileur de là, l'utilisateur sait que quelque chose se passe, sinon on dirait que ça a juste pendu.

alors j'ai ceci:

- (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];
}

Et ensuite, cela est appelé lorsque l'utilisateur choisit "Utiliser":

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

Et ensuite, cela est appelé pour effectuer le traitement pendant que la vignette tourne:

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

Comme je l'ai dit, cela fonctionnait parfaitement avec iOS4, mais avec iOS5, pas de chance.Alors, quelle est l'accord?Le sélecteur d'images se fait licencié éventuellement, alors pourquoi n'est-il pas licencié immédiatement?

Était-ce utile?

La solution

Je ne sais pas pourquoi il y a une disparité entre iOS4 et iOS5 sur ce point. Mais votre description du blocage de l'interface utilisateur est assez cohérente avec le code que vous avez montré. Le sélecteur d'exécution sur le thread principal fait exactement cela, en effectuant le sélecteur sur le thread principal, qui est le thread à partir duquel vous appelez. En raison de ce paramètre waitUntilDone: sur NO n'a pas de sens car il n'est pas envoyé à un autre thread, il s'exécute simplement dans l'ordre. Vous obtiendrez probablement les résultats souhaités simplement en échangeant la commande, comme So:

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

Mais veuillez noter que ce serait au mieux risqué, car je suppose que // processing of image ne contient pas de concurrence. Je préfère les blocs pour la concurrence. Et en plus de cela, j'aime les blocs imbriqués pour rendre la concurrence d'accès facile à suivre, par exemple:

-(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
        });
    });
}

Dans cet esprit, je suggère quelque chose de plus comme ceci:

-(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];
        });
    });
}

Cela déchargerait le travail principal sur un fil d'arrière-plan pour que l'interface utilisateur reste réactive.

Autres conseils

essayer d'utiliser

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

au lieu de:

[[picker parentViewController] dismissModalViewControllerAnimated: YES];

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top