题 UIImagePickerController没有在iOS 8中呈现


是否有其他人有问题 UIImagePickerController 在iOS 8中?下面的方法在iPad上的iOS 7中运行得非常好,但是当我尝试呈现选择器(最后一行)时,我在XCode 6(Beta 3或4)中运行时会出现以下错误。如果重要,则sourceType的选择来自同一位置的alertView。

Warning: Attempt to present <UIImagePickerController: 0x7c0ae400>  on <CAGUCreateContactViewController: 0x7bf61a00> which is already presenting (null)

打开imagePicker的方法。

- (void)openPhotoPicker:(UIImagePickerControllerSourceType)sourceType
{
    if ([UIImagePickerController isSourceTypeAvailable:sourceType]) {
        NSArray *availableMediaTypes = [UIImagePickerController availableMediaTypesForSourceType:sourceType];
        if ([availableMediaTypes containsObject:(NSString *)kUTTypeImage]) {
            UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
            imagePickerController.modalPresentationStyle = UIModalPresentationFullScreen;
            imagePickerController.sourceType = sourceType;
            imagePickerController.mediaTypes = @[(NSString *)kUTTypeImage];
            imagePickerController.delegate = self;

            self.imagePickerController = imagePickerController;

            if (sourceType == UIImagePickerControllerSourceTypeCamera) {
                [self presentViewController:self.imagePickerController animated:YES completion:nil];
            } else {                    
                if (self.popoverVC) {
                    [self.popoverVC dismissPopoverAnimated:YES];
                    self.popoverVC = nil;
                }

                self.popoverVC = [[UIPopoverController alloc] initWithContentViewController:imagePickerController];
                [self.popoverVC presentPopoverFromRect:self.nameAndPicCell.picture.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
            }
        }
    }
}

56
2017-07-24 19:24


起源


你解决了吗? - Tomer Peled
还没有;选择器实际显示,但我仍然在控制台中出错。 - Dave
在iOS 9及以上版本正常运行。 - Radek Wilczak


答案:


我认为这是因为在iOS 8中,警报视图和操作表实际上是视图控制器(UIAlertController)。所以,如果你要呈现一个新的视图控制器来响应来自的动作 UIAlertView,它正在呈现 UIAlertController 被解雇了。我通过延迟演示来解决这个问题 UIImagePickerController 直到runloop的下一次迭代,通过这样做:

[[NSOperationQueue mainQueue] addOperationWithBlock:^{
    [self openPhotoPicker:sourceType];
}];

但是,解决这个问题的正确方法是使用新的 UIAlertController iOS 8上的API(即使用 if ([UIAlertController class]) ......来测试它。如果您尚未使用新API,这只是一种解决方法。


108
2017-09-15 09:49



这对我有用......谢谢 - Tunvir Rahman Tusher
解决这个问题的正确方法是使用新的 UIActionController iOS 8上的API(使用 if ([UIActionController class]) ... 测试它)。如果您尚未使用新API,这只是一种解决方法。 - Ben Lings
这对我不起作用...使用8.1.1 iPad Mini - zezba9000
这适用于带有iOS8的iPhone,但不适用于iPad。 - sheetal
这适用于iphone和ipad dispatch_async(dispatch_get_main_queue()) { // Code here } - aryaxt


我同意Ben Lings问题的检测。在使用UIActionSheet时,我会建议一个更简单的解决方案。我只是简单地移动了我的代码,该代码对Action Sheet选择起反应:

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex;
{
// my code
}

成:

- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex;  // after animation
{
// my code
}

这样,应用程序可以保证在UIActionSheet动画完成后将执行代码。

由于UIAlertView具有类似的委托方法:

- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex;  // after animation
{
// my code
}

我想类似的解决方案可能适用。


80
2017-09-25 20:16



完美的解决方案。谢谢。 - Jim Tierney
这是正确的答案,因为它在iOS7和iOS8下都能正常工作。非常感谢 - Sobakus
这应该是正确的答案。因为NSOperationQueue可以随时更新新版本更新并打破当前选定的答案。 - Drmorgan
我认为这也是正确的方法!但是我认为这是Apple永远无法解决的错误。这是我的情况:我有一个“分享”按钮,显示一个 UIActionSheet 有两个按钮“zip和copy to clipboard”和另一个“print”。制作zip文件需要一段时间,因此在隐藏动画发生时就完成了,这就是我喜欢的原因 clickedButtonAtIndex:。打印机交互控制器与此线程中的照片控制器具有相同的限制,因此它必须从中开始 didDismissWithButtonIndex: 这意味着我需要将我的逻辑划分为两种方法?真是一团糟! - nacho4d
我会更高兴他们在一种方法中添加了两个完成调用。一个可以让您在用户点击按钮后尽快做出反应,而其他可以让您继续使用相同点击和操作的结果更新UI。但这会破坏他们简单的API模式会/事件。 - vedrano


这是一个适合我的解决方案

if([[[UIDevice currentDevice] systemVersion] floatValue]>=8.0)
{
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{

        [self presentViewController:cameraUI animated:NO completion:nil];
    }];

}
else{

    [controller presentViewController:cameraUI animated:NO completion:nil];
}

记得分配 cameraUI

UIImagePickerController *cameraUI = [[UIImagePickerController alloc] init];
cameraUI.sourceType = UIImagePickerControllerSourceTypeCamera;

建立和去!


12
2017-09-16 10:07





我在iOS 8中遇到了同样的问题。 然后我在设备上看到了iOS的最新更新的更改日志,即8.0.2。

本次更新中提到_

“修复了导致某些应用无法访问照片库中的照片的问题”

因此,在iOS 8.0.2版本的设备上使用XCode 6测试您的应用程序,它可以正常工作 不要在iOS 8.0模拟器上测试它。

这对我有所帮助,希望对你有所帮助。

Screen-shot of iOS 8.0.2 Update change log


8
2017-09-27 12:39





UIImagePickerController *imagePickerController= [[UIImagePickerController alloc] init];
[imagePickerController setSourceType:UIImagePickerControllerSourceTypePhotoLibrary];

// image picker needs a delegate so we can respond to its messages
[imagePickerController setDelegate:self];
self.shouldCallViewWillAppear = NO;

if(IS_IOS8)
{
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
        // Place image picker on the screen
        [self presentViewController:imagePickerController animated:YES completion:nil];
    }];
}
else
{
    [self presentViewController:imagePickerController animated:YES completion:nil];
}

4
2017-09-22 12:47





您可以使用删除显示的视图控制器(如果有)

[self.presentedViewController dismissViewControllerAnimated:YES completion:nil];

这对我有用。


3
2018-06-29 11:22



这对我有用 - 只需在显示新视图控制器之前插入此行。为什么这没有更多的投票?有没有人对此解决方案有任何疑问? - IanS


您需要做的就是解雇已经呈现的ViewController:

if (self.presentedViewController) {
    [self.presentedViewController dismissViewControllerAnimated:YES completion:nil];
}

[self openPhotoPicker:sourceType];

如果仍然产生错误,请将openPhotoPicker:放入完成处理程序


2
2017-10-13 11:46



谢谢英雄。像魅力一样工作。 - Monu singh


我只是这样做:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND,
                                         (unsigned long)NULL), ^(void) {

    [self retractActivePopover];

    dispatch_async(dispatch_get_main_queue(), ^ {

        _activePopover=imagePickerPopover;

        UIBarButtonItem *callingButton = (UIBarButtonItem*) sender;

        [imagePickerPopover presentPopoverFromBarButtonItem:callingButton permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];

    });

});

1
2017-09-24 19:28