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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 14:48:21