【问题标题】:UIImagePickerController crash only on iOS 7 - iPadUIImagePickerController 仅在 iOS 7 上崩溃 - iPad
【发布时间】:2013-09-27 04:27:27
【问题描述】:

自从人们开始升级到 iOS 7 以来,我的一个实时应用程序发生了数百次崩溃。其他人看到过这个问题吗?在装有 iOS 7 的 iPad 3 上无法重现...

Crashlytics 链接:crashes.to/s/edf2e71d9a5

Fatal Exception CALayerInvalidGeometry
CALayer position contains NaN: [nan nan]
0 ...    CoreFoundation  __exceptionPreprocess + 130
2    CoreFoundation  -[NSException initWithCoder:]
3    QuartzCore      CA::Layer::set_position(CA::Vec2<double> const&, bool) + 242
4    QuartzCore  -[CALayer setPosition:] + 54
5    QuartzCore  -[CALayer setFrame:] + 594
6    UIKit   -[UIView(Geometry) setFrame:] + 254
7    UIKit   -[UILabel setFrame:] + 138
8    UIKit   -[UINavigationItemView initWithNavigationItem:] + 384
9    UIKit   -[UINavigationItem _titleView] + 92
10   UIKit   -[UINavigationBar _prepareForPushAnimationWithItems:] + 68
11   UIKit   -[UINavigationBar pushNavigationItem:] + 292
12   UIKit   -[UINavigationBar _pushNavigationItem:transition:] + 386
13   UIKit   __71-[UINavigationController pushViewController:transition:forceImmediate:]_block_invoke + 150
14   UIKit   -[UINavigationController pushViewController:transition:forceImmediate:] + 1384
15   UIKit   -[UINavigationController pushViewController:animated:] + 294
16   UIKit   -[UIImagePickerController _setupControllersForCurrentSourceType] + 112
17   UIKit   -[UIImagePickerController setSourceType:] + 456
18 ...   libdispatch.dylib   _dispatch_call_block_and_release + 10
19   libdispatch.dylib   _dispatch_client_callout + 22
20   libdispatch.dylib   _dispatch_main_queue_callback_4CF$VARIANT$mp + 268
21   CoreFoundation  __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 8
22   CoreFoundation  __CFRunLoopRun + 1300
23   CoreFoundation  CFRunLoopRunSpecific + 522
24   CoreFoundation  CFRunLoopRunInMode + 106
25   GraphicsServices    GSEventRunModal + 138
26   UIKit   UIApplicationMain + 1136

【问题讨论】:

  • 我们无法在测试中发生异常。我们只从 Crashlytics 获知它,并假设它会从应用程序中崩溃。
  • 我得到了同样的结果 - 让我们比较一下笔记。我假设这从 UIImagePickerController 开始。我将它用于相机和照片库访问。我怀疑这在访问照片库期间由于导航栏的东西而崩溃。我将图像选择器放在 UIPopoverController 中并将其呈现给用户 - 也许与它有关?
  • 我只在这种情况下得到同样的结果:我第一次从 iPad 上的 uibarbuttonitem 调出库版本的选择器。系统要求用户授予访问照片库的权限。用户说是,我得到了崩溃。
  • 从访问照片库的 UIBarButtonItem 在 iOS 7 上的 iPad 上显示 UIImagePickerController 时遇到此问题。有人知道如何重置照片隐私,以便再次显示照片隐私消息吗?
  • 建议的解决方法是调用 ALAssetLibrary 来获取缩略图图像或其他可以工作或导致对话框显示的东西。然后在回调的块中,显示图像选择器。

标签: ios ipad uiimagepickercontroller ios7


【解决方案1】:

总的来说,我们得出的结论是,这是 iPad 上 iOS 7 中的一个错误。当您第一次尝试从 UIBarButtonItem 在 UIPopoverControl 中显示 UIImagePickerController 时,就会发生这种情况。在用户授予他们的相册权限后,就会发生崩溃。目前的解决方案似乎是在打开 UIPopoverControl 之前请求照片的权限。以下是我实施解决方案的方式:

// Photo Library
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary])
{
    void(^blk)() =  ^() {
        UIImagePickerController* picker = [[UIImagePickerController alloc] init];
        picker.delegate = self;
        picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
        if (NIIsPad()) {
            UIPopoverController* popover = [[UIPopoverController alloc] initWithContentViewController:picker];
            [popover presentPopoverFromBarButtonItem:self.popoverAnchor permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
        } else {
            [self.navigationController presentModalViewController:picker animated:YES];
        }
    };

    // Make sure we have permission, otherwise request it first
    ALAssetsLibrary* assetsLibrary = [[ALAssetsLibrary alloc] init];
    ALAuthorizationStatus authStatus;
    if (IOS_VERSION_GREATER_THAN_OR_EQUAL_TO(@"6.0"))
        authStatus = [ALAssetsLibrary authorizationStatus];
    else
        authStatus = ALAuthorizationStatusAuthorized;

    if (authStatus == ALAuthorizationStatusAuthorized) {
        blk();
    } else if (authStatus == ALAuthorizationStatusDenied || authStatus == ALAuthorizationStatusRestricted) {
        [[UIAlertView alertViewWithTitle:@"Grant photos permission" message:@"Grant permission to your photos. Go to Settings App > Privacy > Photos."] show];
    } else if (authStatus == ALAuthorizationStatusNotDetermined) {
        [assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
            // Catch the final iteration, ignore the rest
            if (group == nil)
                dispatch_async(dispatch_get_main_queue(), ^{
                    blk();
                });
            *stop = YES;
        } failureBlock:^(NSError *error) {
            // failure :(
            dispatch_async(dispatch_get_main_queue(), ^{
                [[UIAlertView alertViewWithTitle:@"Grant photos permission" message:@"Grant permission to your photos. Go to Settings App > Privacy > Photos."] show];
            });
        }];
    }
}

不要忘记将 AssetsLibrary.framework 添加到您的项目中。

【讨论】:

  • 仅供参考,我向 Apple 提交了一个错误,编号为 15077496
  • kurtzmarc 感谢您发布此信息。我很惊讶这能通过 Apple 的 QA...
  • 我在 Apple 的网站上找不到该错误报告。是否标记为私有?
  • 我在错误报告中看不到任何地方可以切换公共/私人
  • nvm - 你看不到其他人的错误报告(因此需要开放式雷达)。我忘记了。
【解决方案2】:

我遇到了同样的问题。

我在 UIPopoverController 中显示了一个 UIImagePickerController,其大小由 UIImagePickerController 的 contentSizeForViewInPopover 函数定义。
为了解决这个问题,我将UIPopoverController 的大小更改为UIImagePickerController's preferredContentSize 函数。

【讨论】:

    【解决方案3】:

    您可以使用自定义框架并如下加载弹出框

    [popOver presentPopoverFromRect:CGRectMake(self.view.frame.size.width-50, 50, 10, 10) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-01-04
      • 2014-03-02
      • 1970-01-01
      • 2012-11-26
      • 2011-12-10
      • 2013-11-22
      • 2012-01-17
      相关资源
      最近更新 更多