You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

KMM(Compose Multiplatform)中UIImagePickerController的didFinishPickingMediaWithInfo未触发

解决KMM Compose Multiplatform中拍照后UIImagePickerController回调不触发的问题

针对你的代码中相册功能正常、但拍照后imagePickerController回调未触发的问题,可从以下几个关键点排查修复:

1. 修复Delegate的内存管理问题

UIKit中UIImagePickerController的delegate是弱引用,你的匿名cameraDelegate仅靠remember持有,在iOS ARC机制下可能被提前释放,导致拍照完成时找不到回调对象。

修改rememberOpenCameraAction,将delegate与控制器绑定,确保强引用持有:

@Composable
fun rememberOpenCameraAction(onImageSelected:(ImageBitmap) -> Unit): () -> Unit {
    val uiViewController = LocalUIViewController.current
    return remember {
        val cameraDelegate = object : NSObject(), UIImagePickerControllerDelegateProtocol, UINavigationControllerDelegateProtocol {
            override fun imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo: Map<Any?, *>) {
                // 优先取编辑后的图片,无编辑则取原始图
                val uiImage = didFinishPickingMediaWithInfo[UIImagePickerControllerEditedImage] as? UIImage
                    ?: didFinishPickingMediaWithInfo[UIImagePickerControllerOriginalImage] as? UIImage
                uiImage?.let { onImageSelected(it.toImageBitmap()) }
                picker.dismissViewControllerAnimated(flag = true, completion = {})
            }

            // 实现取消回调,确保控制器能正常关闭
            override fun imagePickerControllerDidCancel(picker: UIImagePickerController) {
                picker.dismissViewControllerAnimated(flag = true, completion = {})
            }
        }

        {
            val cameraController = UIImagePickerController()
            cameraController.setSourceType(UIImagePickerControllerSourceType.UIImagePickerControllerSourceTypeCamera)
            cameraController.setAllowsEditing(true)
            cameraController.setCameraCaptureMode(UIImagePickerControllerCameraCaptureMode.UIImagePickerControllerCameraCaptureModePhoto)
            cameraController.setDelegate(cameraDelegate)
            // 给控制器添加强引用关联,防止delegate被ARC回收
            cameraController.setValue(cameraDelegate, forKey = "customDelegate")
            uiViewController.presentViewController(cameraController, animated = true, completion = null)
        }
    }
}

2. 检查iOS相机权限配置

在iOS项目的Info.plist中必须添加相机权限描述,否则相机功能可能出现异常(即使能打开相机,也可能导致回调中断):

<key>NSCameraUsageDescription</key>
<string>需要访问相机来拍摄照片</string>

3. 补充取消回调实现

未实现imagePickerControllerDidCancel方法会导致用户点击取消时控制器无法正常关闭,还可能引发生命周期异常,务必在delegate中补充该方法。

4. 完善图片获取逻辑

当开启编辑模式setAllowsEditing(true)时,若用户拍照后直接确认不编辑,UIImagePickerControllerEditedImage会为空,此时需 fallback 到UIImagePickerControllerOriginalImage获取原始图片,避免回调触发却拿不到图片的情况。

按上述步骤修改后,拍照的回调即可正常触发。

内容的提问来源于stack exchange,提问作者Lubomir Babev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 06:05:34