iOS14下用PHPickerViewController替换UIImagePickerController后选中照片不更新UI
问题原因
- 未校验
NSItemProvider是否支持加载UIImage类型,也没有处理加载错误逻辑,iCloud同步的照片、特殊格式资源会出现加载无返回的情况 - iOS 14部分小版本存在
loadObject(ofClass: UIImage.self)回调不触发的已知兼容问题 - 资源加载闭包未对当前控制器做弱引用,极端情况下会出现循环引用导致UI更新逻辑不执行
修复方案
替换原有代理实现代码为以下版本,适配iOS 14+的PHPicker加载逻辑,需先在文件顶部导入UniformTypeIdentifiers框架:
extension EditProfileController: PHPickerViewControllerDelegate { @available(iOS 14, *) func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) { picker.dismiss(animated: true) // 单选场景直接取第一个结果,多选可保留原有遍历逻辑 guard let result = results.first else { return } let itemProvider = result.itemProvider // 先校验是否支持加载图片类型 guard itemProvider.canLoadObject(ofClass: UIImage.self) else { return } itemProvider.loadObject(ofClass: UIImage.self) { [weak self] object, error in // 处理加载错误 if let error = error { print("图片加载失败: \(error.localizedDescription)") // 可自行添加加载失败的用户提示逻辑 return } guard let image = object as? UIImage else { // loadObject加载失败时用loadDataRepresentation兜底 if itemProvider.hasItemConformingToTypeIdentifier(UTType.image.identifier) { itemProvider.loadDataRepresentation(forTypeIdentifier: UTType.image.identifier) { data, _ in guard let data = data, let image = UIImage(data: data) else { return } DispatchQueue.main.async { self?.profileImageView.image = image self?.imageChanged = true } } } return } DispatchQueue.main.async { self?.profileImageView.image = image self?.imageChanged = true } } } }
额外校验项
确认PHPicker初始化逻辑符合要求,避免配置错误导致加载失败:
// 正确的PHPicker初始化示例 var config = PHPickerConfiguration() config.filter = .images // 限制只能选择图片 config.selectionLimit = 1 // 单选场景设置为1,多选可调整对应数值 let picker = PHPickerViewController(configuration: config) picker.delegate = self present(picker, animated: true)
内容的提问来源于stack exchange,提问作者safetotry
相关产品推荐
相关产品推荐

