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
相关产品推荐
相关产品推荐

