Hey, guys and girls, I’m trying to implement imag...
# compose-ios
b
Hey, guys and girls, I’m trying to implement image picker from photo library and camera with compose multiplatform for Android and iOS. In Android everything works great. I have a problem with iOS: I have an expected composable function in the common part :
Copy code
@Composable
expected fun ImagePickerView()
in the iOS shared part it is :
Copy code
@Composable
actual fun ImagePickerView() {
    var bitmap by remember { mutableStateOf<ImageBitmap?>(null) }
    Box {
        Column(
            modifier = Modifier
                .align(Alignment.BottomCenter)
                .padding(bottom = 32.dp),
            horizontalAlignment = Alignment.CenterHorizontally,
        ) {
            bitmap?.let {
                Image(bitmap = it, contentDescription = null)
            }
            Button(
                onClick = rememberOpenPickerAction { image ->
                    bitmap = image
                },
            ) {
                Text(text = "Select Image")
            }
            Button(
                modifier = Modifier.padding(top = 16.dp),
                onClick = rememberOpenCameraAction { image ->
                    bitmap = image
                },
            ) {
                Text(text = "Take photo")
            }
        }
    }
}


@Composable
fun rememberOpenPickerAction(onImageSelected:(ImageBitmap) -> Unit): () -> Unit {
    val uiViewController = LocalUIViewController.current
    val cameraDelegate = remember {
        object : NSObject(), UIImagePickerControllerDelegateProtocol, UINavigationControllerDelegateProtocol {
            override fun imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo: Map<Any?, *>) {
                val uiImage = didFinishPickingMediaWithInfo[UIImagePickerControllerEditedImage] as? UIImage
                uiImage?.let { onImageSelected(it.toImageBitmap()) }
                picker.dismissViewControllerAnimated(flag = false, completion = {})
            }
        }
    }

    return remember {
        {
            val cameraController = UIImagePickerController()
            cameraController.setSourceType(UIImagePickerControllerSourceType.UIImagePickerControllerSourceTypePhotoLibrary)
            cameraController.setAllowsEditing(true)
            cameraController.setDelegate(cameraDelegate)
            uiViewController.presentViewController(cameraController, animated = true, completion = null)
        }
    }
}

@Composable
fun rememberOpenCameraAction(onImageSelected:(ImageBitmap) -> Unit): () -> Unit {
    val uiViewController = LocalUIViewController.current
    val cameraDelegate = remember {
        object : NSObject(), UIImagePickerControllerDelegateProtocol, UINavigationControllerDelegateProtocol {
            override fun imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo: Map<Any?, *>) {
                val uiImage = didFinishPickingMediaWithInfo[UIImagePickerControllerEditedImage] as? UIImage
                uiImage?.let { onImageSelected(it.toImageBitmap()) }
                picker.dismissViewControllerAnimated(flag = false, completion = {})
            }
        }
    }

    return remember {
        {
            val cameraController = UIImagePickerController()
            cameraController.setSourceType(UIImagePickerControllerSourceType.UIImagePickerControllerSourceTypeCamera)
            cameraController.setAllowsEditing(true)
            cameraController.setDelegate(cameraDelegate)
            uiViewController.presentViewController(cameraController, animated = true, completion = null)
        }
    }
}
With rememberOpenPickerAction everything works great, but with rememberOpenCameraAction, the delegate function imagePickerController is never called. I’ve researched a lot in internet and I’ve found that the problem may be from the delegate function, because in some version of Swift (Swift 5 I think), Apple had changed the function to be: optional func imagePickerController( _ picker:
UIImagePickerController
, didFinishPickingMediaWithInfo info: [
UIImagePickerController
.
InfoKey
: Any]) The difference is in the NSDictonary didFinishPickingMediaWithInfo to be with key of type
UIImagePickerController
.
InfoKey
and not Any. But this function isn’t implemented in the UIImagePickerControllerDelegateProtocol. Has anyone faced this problem? I’ll be happy if somebody share how to get the image(UIimage) after the Camera controller.
3
s
Have you found the fix?
223 Views