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

SwiftUI中UIHostingController内DismissAction无法生效问题排查

问题原因及解决方案

问题根源

你遇到的问题是因为SwiftUI的@Environment(\.dismiss)默认只适配SwiftUI自身的展示机制(比如sheet、fullScreenCover,或是NavigationStack的页面跳转),而你当前是通过UIKit的present(_:animated:completion:)方法展示包裹着UIHostingController的UINavigationController,这种情况下SwiftUI的dismiss环境变量无法关联到UIKit的控制器dismissal逻辑,所以调用dismiss()没有任何反应。

解决方案一:手动注入DismissAction

在创建UIHostingController时,手动给SwiftUI视图注入指向UIKit dismiss操作的DismissAction,这样点击Done按钮就能触发UIKit的控制器关闭逻辑。修改你的ViewController代码如下:

class ViewController: UIViewController {
  override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    
    let testView = TestView()
    let hostingController = UIHostingController(rootView: testView)
    let navController = UINavigationController(rootViewController: hostingController)
    
    // 手动注入关联UIKit dismiss的DismissAction
    hostingController.rootView.environment(\.dismiss, DismissAction {
      navController.dismiss(animated: true)
    })
    
    self.present(navController, animated: true)
  }
}

解决方案二:改用SwiftUI的Sheet展示(推荐场景适配时使用)

如果你的业务场景允许,改用SwiftUI原生的sheet机制来展示TestView,此时@Environment(\.dismiss)会自动生效,无需额外配置。示例代码如下:

首先修改ViewController,嵌入一个负责触发展示的SwiftUI视图:

class ViewController: UIViewController {
  override func viewDidLoad() {
    super.viewDidLoad()
    
    let presentingView = UIHostingController(rootView: PresentingView())
    addChild(presentingView)
    presentingView.view.frame = view.bounds
    view.addSubview(presentingView.view)
    presentingView.didMove(toParent: self)
  }
}

// 负责触发弹窗的SwiftUI视图
struct PresentingView: View {
  @State private var isTestViewPresented = false
  
  var body: some View {
    Button("打开测试视图") {
      isTestViewPresented = true
    }
    .sheet(isPresented: $isTestViewPresented) {
      TestView()
        .navigationBarTitleDisplayMode(.inline)
    }
  }
}

你的TestView代码无需改动,点击Done按钮时dismiss()会自动关闭sheet。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 21:42:41