我有一个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,没有这样的运气。那是什么交易?图像选择器最终被解雇,为什么不立即被解雇?
答案 0 :(得分:4)
我不确定为什么iOS4
&之间存在差异? iOS5
就这一点而言。但是您对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保持响应。
答案 1 :(得分:0)
尝试使用
[[picker presentingViewController] dismissViewControllerAnimated:YES completion:nil];
而不是:
[[picker parentViewController] dismissModalViewControllerAnimated: YES];