iOS15中PHPickerViewController取消按钮点击无响应无法关闭
问题根因
PHPickerViewController没有提供独立的取消点击回调,无论用户是选中了图片还是点击了自带的Cancel按钮,都会触发picker(_:didFinishPicking:)代理方法:
- 用户选中图片时,
results数组内会返回选中的资源结果 - 用户点击Cancel按钮时,
results数组为空数组
你当前的实现直接对results.first调用资源加载方法,当results为空时results.first为nil,后续所有包含dismiss调用的逻辑分支都不会执行,因此选择器无法正常关闭。
修复代码
只需要在代理方法最开头增加空结果判断,识别到用户取消操作时直接dismiss控制器即可,修正后的完整代理实现如下:
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) { // 处理取消点击场景 guard let selectedResult = results.first else { picker.dismiss(animated: true) return } // 原有选中图片的处理逻辑 selectedResult.itemProvider.loadObject(ofClass: UIImage.self) { [unowned self] reading , error in guard let image = reading as? UIImage, error == nil else { DispatchQueue.main.async { picker.dismiss(animated: true) self.profilePictureHasError = true self.toggleDoneButtonEnabled() } return } self.profilePictureHasError = false DispatchQueue.main.async { picker.dismiss(animated: true) self.profilePictureHasChanged = self.userProfilePicture != image if self.profilePictureHasChanged { self.profilePictureView.image = image self.toggleDoneButtonEnabled() } } } }
补充说明
picker(_:didFinishPicking:)代理方法本身就是在主线程回调,取消场景下的dismiss可以直接调用,不需要额外套DispatchQueue.main.async,如果为了逻辑统一加也不会有问题- 该逻辑对单选、多选模式都生效:只要是用户主动点击取消按钮退出选择器,返回的
results一定是空数组 - 不需要自行给
PHPickerViewController添加自定义取消按钮覆盖系统原有按钮,避免出现交互异常
内容的提问来源于stack exchange,提问作者Kris2k
相关产品推荐
相关产品推荐

