调用UIImagePickerController提供黑屏

时间:2018-02-12 14:45:08

标签: ios uiimagepickercontroller

我试图从图库中获取照片以将其发送到api。当我拨打AttachNewFileClick()时,会出现黑屏。

@IBAction func AttachNewFileClick(_ sender: Any) {
    if checkPhotoAccess()==true {
        let imagePicker = UIImagePickerController(rootViewController: self)
        imagePicker.delegate = self
        imagePicker.sourceType = .photoLibrary
        imagePicker.mediaTypes = UIImagePickerController.availableMediaTypes(for: .photoLibrary)!
        present(imagePicker, animated: true, completion: nil)
    }
}

func checkPhotoAccess() -> Bool {
    let status:PHAuthorizationStatus = PHPhotoLibrary.authorizationStatus();
    switch status {
    case PHAuthorizationStatus.notDetermined:
        PHPhotoLibrary.requestAuthorization({status in
            return
        })
        return checkPhotoAccess()
    case .denied:
        return false
    case .restricted:
        let permissionRequestAlert:UIAlertView = UIAlertView(title: "Доступ к галлерее заблокирован", message: "Приложение не может получить доступ к вашей галлерее для прикрепления фото. Вероятно ранее вы заблокировали эту возможность", delegate: self, cancelButtonTitle: "Отмена", otherButtonTitles: "Открыть настройки")
        permissionRequestAlert.tag = PERMISSION_REQUEST_ALERT_TAG
        permissionRequestAlert.show()
        return false
    case .authorized:
        return true
    }
}

然后我在所有异常中添加了断点,并在抛出异常之前突出显示了这段代码

  

libobjc.A.dylib`objc_exception_throw:    - > 0x1159b0f11< + 0>:pushq%rbp

日志中的

和异常:

  

由于未捕获的异常终止应用程序' NSInvalidArgumentException',原因:' *** - [__ NSDictionaryM setObject:forKey:]:key不能为nil'

我在模拟器iPhone SE(11.2 Xcode 9.2)中运行应用程序。 Project min iOS版本是8.2。 UIImagePickerControllerNavigationViewController中调用了public abstract class Armor { public abstract void Equip( MainCharacterEquipment mce ); } public class HeadArmor : Armor { public override void Equip( MainCharacterEquipment mce ) { mce.HeadSlot=this; } } public class ChestArmor : Armor { public override void Equip( MainCharacterEquipment mce ) { mce.ChestSlot=this; } }

如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

你崩溃的原因是这一行:

let imagePicker = UIImagePickerController(rootViewController: self)

这不是你如何创建UIImagePickerController。只需创建它!它已经拥有了自己的根视图控制器;不要试图改变它。只是说:

let imagePicker = UIImagePickerController()

此外,您的checkPhotoAccess代码存在致命缺陷:

func checkPhotoAccess() -> Bool {
    let status:PHAuthorizationStatus = PHPhotoLibrary.authorizationStatus();
    switch status {
    case PHAuthorizationStatus.notDetermined:
        PHPhotoLibrary.requestAuthorization({status in
            return
        })
        return checkPhotoAccess()
    case .denied:
        return false
    case .restricted:
        let permissionRequestAlert:UIAlertView = UIAlertView(title: "Доступ к галлерее заблокирован", message: "Приложение не может получить доступ к вашей галлерее для прикрепления фото. Вероятно ранее вы заблокировали эту возможность", delegate: self, cancelButtonTitle: "Отмена", otherButtonTitles: "Открыть настройки")
        permissionRequestAlert.tag = PERMISSION_REQUEST_ALERT_TAG
        permissionRequestAlert.show()
        return false
    case .authorized:
        return true
    }
}

要了解原因,让我们消除除notDetermined案例之外的所有事情:

func checkPhotoAccess() -> Bool {
    PHPhotoLibrary.requestAuthorization({status in
        return
    })
    return checkPhotoAccess()
}

现在想想那些行将执行的 order requestAuthorization异步。因此执行顺序如下:

func checkPhotoAccess() -> Bool {
    PHPhotoLibrary.requestAuthorization({status in
        return // 2
    })
    return checkPhotoAccess() // 1
}

好的,但是2 永远不会执行,因为1首先返回。所以我们留下了这个:

func checkPhotoAccess() -> Bool {
    return checkPhotoAccess()
}

但这显然是疯了。我们有一个无限的递归。

需要注意的是无法checkPhotoAccess返回值,因为您需要调用异步的requestAuthorization。实现此类事情的正确方法是在false情况下返回.notDetermined,否则(更好)编写接收完成函数<的<{1}}方法/ em>然后,如果发现我们有授权,则可以调用该函数。

此外,您需要立即停止使用UIAlertView并转换为UIAlertController。 UIAlertView已被弃用 long 之前。编译器会警告你这个,所以请听听它告诉你的内容!