【问题标题】:Why won't dismissmodalviewcontrolleranimated dismiss UIImagePickerController immediately on ios5?为什么没有dismissmodalviewcontrolleranimated 在ios5 上立即关闭UIImagePickerController?
【发布时间】:2012-01-14 14:50:59
【问题描述】:

我有一个 UITableViewController,它弹出一个 UIImagePickerController,用户拍照,点击使用按钮,在处理图像时,Picker 关闭以显示自定义缩略图微调器,然后微调器在最后被实际缩略图替换处理。

至少它在 iOS4 中是这样工作的。现在使用 iOS5,它只是坐在那里处理直到完成,然后一切正常。但我想要那个微调器,以便用户知道发生了什么事情,否则它看起来就像刚刚挂起。

所以我有这个:

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

然后当用户选择“使用”时调用它:

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

然后在缩略图旋转时调用它来执行处理:

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

就像我说的,它在 iOS4 上完美运行,但在 iOS5 上,就没有这样的运气了。那么有什么关系呢?图像选择器最终会被关闭,为什么不立即关闭呢?

【问题讨论】:

  • 我真的不知道为什么这很重要,但是您是否尝试将 [self performSelector... 替换为 dispatch_async(dispatch_get_main_queue(), ^{[self processImage:info];});
  • 好主意,但行为相同。至少我学到了一些新东西!

标签: ios5 uiimagepickercontroller spinner dismiss


【解决方案1】:

我不确定为什么 iOS4iOS5 在这一点上存在差异。但是您对 UI 挂起的描述与您显示的代码相当一致。主线程上的执行选择器就是这样做的,它在主线程上执行选择器,主线程是您从中调用的线程。因为这个设置waitUntilDone:NO 是没有意义的,因为它没有被发送到另一个线程,它只是按顺序运行。您可能会通过交换订单获得所需的结果,例如:

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

但请注意,这充其量是有风险的,因为我假设// processing of image 不包含并发。我更喜欢并发块。最重要的是,我喜欢嵌套块以使并发易于遵循,例如:

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

因此,考虑到这一点,我建议更像这样:

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

这会将主要工作卸载到后台线程,以让 UI 保持响应。

【讨论】:

  • 完美!这正是我想要的,我也学到了一些东西。实际上,我现在记得在我参加的课程中学到了类似的东西,但我想它并没有坚持下去。谢谢!
【解决方案2】:

尝试使用

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

代替:

[[picker parentViewController] dismissModalViewControllerAnimated: YES];

【讨论】:

  • 欢迎来到 Stack Overflow!谢谢你的帖子!请不要在您的帖子中使用签名/标语。您的用户框算作您的签名,您可以使用您的个人资料发布您喜欢的任何关于您自己的信息。 FAQ on signatures/taglines
猜你喜欢
  • 1970-01-01
  • 2019-03-31
  • 2020-12-04
  • 1970-01-01
  • 1970-01-01
  • 2014-04-28
  • 2017-02-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多