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

SwiftUI集成PHPickerViewController点击搜索栏报无法加载照片错误

根因

这是iOS 15系统的已知缺陷,和TCA架构无关,问题出在SwiftUI模态转场动画与系统照片选择器扩展进程的冲突:

  • PHPicker、UIImagePicker在iOS15上运行在独立的系统扩展进程中,不属于App本身的进程
  • 点击搜索栏触发键盘弹出时,SwiftUI默认的模态转场动画逻辑会和扩展进程的UI更新逻辑冲突,导致系统直接kill掉照片选择器的扩展进程,因此会出现Connection to plugin invalidated报错和无法加载的提示
  • 录屏时系统会全局禁用部分非核心动画,冲突逻辑不会触发,因此问题不会复现;UIKit的present动画逻辑和SwiftUI不同,不会触发该冲突,因此UIKit测试项目运行正常

可行解决方案

该问题在iOS 16及以上版本已经被苹果官方修复,仅需要对iOS 15版本做兼容处理即可,可任选以下方案:

  • 方案1:弹出选择器时禁用模态动画(改动最小、兼容性最高)
    在触发弹出sheet的逻辑中,iOS15版本禁用动画即可:
    Button("选择照片") {
        if #available(iOS 16, *) {
            showPicker = true
        } else {
            // iOS15下禁用动画弹出
            withAnimation(nil) {
                showPicker = true
            }
        }
    }
    .sheet(isPresented: $showPicker) {
        ImagePicker(store: store)
    }
    
  • 方案2:修改UIViewControllerRepresentable实现,不直接返回PHPicker实例
    外层套一个空白的UIViewController,通过空白VC来present PHPicker,规避SwiftUI直接管理选择器VC的布局动画问题,核心逻辑如下:
    public func makeUIViewController(context: Context) -> UIViewController {
        // 创建空白VC作为载体
        let dummyVC = UIViewController()
        // 配置PHPicker
        var config = PHPickerConfiguration()
        config.filter = .images
        let picker = PHPickerViewController(configuration: config)
        picker.delegate = context.coordinator
        // 空白VC加载完成后自动弹出选择器
        DispatchQueue.main.async {
            dummyVC.present(picker, animated: true)
        }
        return dummyVC
    }
    // 对应调整Coordinator的关闭逻辑:先dismiss PHPicker,再触发外层SwiftUI的sheet关闭
    
  • 方案3:完全使用UIKit逻辑弹出选择器
    直接获取当前根VC,用UIKit的present方法弹出PHPicker实例,完全绕开SwiftUI的sheet管理逻辑,和UIKit测试项目的实现逻辑完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 21:00:02