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

KMM中无法使用PHPickerViewController代理的问题求助

解决方案

问题核心出在代理对象的生命周期管理,同时优化方法签名即可解决,具体修复点如下:

1. 强引用持有代理对象,避免被GC回收

PHPickerViewController的delegate是弱引用,你之前的代码中代理是局部匿名对象,函数执行完毕后没有任何强引用持有它,Kotlin/Native的垃圾回收器会提前回收这个对象,导致点击Cancel时找不到代理响应回调。

用Compose的remember函数持有代理对象,确保它的生命周期与Composable一致,不会被提前回收。

2. 明确方法参数类型,匹配Objective-C协议签名

将List<*>改为List<PHPickerResult>,让类型更明确,确保Objective-C能正确识别方法签名,避免因泛型星号导致的方法匹配失败。

3. 移除多余的dismiss操作

你同时调用了picker和uiViewController的dismiss方法,其实只需要调用picker的dismissViewControllerAnimated即可——因为picker是被uiViewController present的,dismiss picker会自动完成模态窗口的关闭。

修改后的完整代码

import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.interop.LocalUIViewController
import platform.PhotosUI.PHPickerConfiguration
import platform.PhotosUI.PHPickerViewController
import platform.PhotosUI.PHPickerViewControllerDelegateProtocol
import platform.PhotosUI.PHPickerResult
import platform.darwin.NSObject

@Composable
actual fun pickerController() {
    val uiViewController = LocalUIViewController.current
    val configuration = PHPickerConfiguration()
    val pickerController = PHPickerViewController(configuration)
    
    // 用remember强引用代理,防止被GC回收
    val pickerDelegate = remember {
        object : NSObject(), PHPickerViewControllerDelegateProtocol {
            override fun picker(picker: PHPickerViewController, didFinishPicking: List<PHPickerResult>) {
                println("didFinishPicking: $didFinishPicking")
                picker.dismissViewControllerAnimated(flag = true, completion = {})
            }
        }
    }

    pickerController.delegate = pickerDelegate
    uiViewController.presentViewController(pickerController, animated = true, completion = null)
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 04:12:32