iOS 16下SwiftUI实现的Share Extension不显示问题排查
问题根因
这个问题不属于iOS 16系统Bug,也不是遗漏了WWDC公布的Share Extension规则变更,核心原因是SwiftUI视图嵌入逻辑不符合控制器层级规范:iOS 15下能正常运行属于系统兼容逻辑下的意外表现,iOS 16收紧了扩展入口控制器的视图层级校验,缺失父子控制器绑定的视图会被直接拦截不渲染。
原有代码存在两个核心问题:
- 仅将
UIHostingController的视图直接添加到UINavigationController的根view上,没有完成完整的父子控制器绑定流程 - 手动添加子视图的方式绕过了
UINavigationController的栈管理逻辑,在iOS 16的扩展远程视图环境下会触发视图层级校验失败
修复方案
直接将承载SwiftUI视图的UIHostingController设置为导航控制器的根视图控制器即可,不需要手动添加子视图约束,修改后的核心代码如下:
// ShareNavigationController.swift import Foundation import UIKit import SwiftUI import Social @objc(ShareNavigationController) class ShareNavigationController: UINavigationController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) setNavigationBarHidden(true, animated: false) } override func viewDidLoad() { super.viewDidLoad() setNavigationBarHidden(true, animated: false) setupSwiftUIRoot() } private func setupSwiftUIRoot() { let rootView = AddURLView(viewModel: AddURLViewModel(extensionContext: self.extensionContext)) let hostingController = UIHostingController(rootView: rootView) // 直接设置为导航栈根控制器,由系统自动管理视图层级 setViewControllers([hostingController], animated: false) } }
如果你确实需要手动布局子视图(比如要在SwiftUI视图下加自定义原生控件),必须补全完整的父子控制器绑定流程,不能只添加view:
private func initSwiftUI() { let rootView = AddURLView(viewModel: AddURLViewModel(extensionContext: self.extensionContext)) let controller = UIHostingController(rootView: rootView) // 补全父子控制器绑定 addChild(controller) view.addSubview(controller.view) controller.didMove(toParent: self) controller.view.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ controller.view.topAnchor.constraint(equalTo: view.topAnchor), controller.view.bottomAnchor.constraint(equalTo: view.bottomAnchor), controller.view.leftAnchor.constraint(equalTo: view.leftAnchor), controller.view.rightAnchor.constraint(equalTo: view.rightAnchor) ]) }
额外注意事项
- 你当前的Info.plist配置符合iOS 16要求,不需要修改,只要确保没有多余的
NSExtensionMainStoryboard配置项即可(该配置项和NSExtensionPrincipalClass同时存在时会在iOS16下触发扩展加载失败) - 如果修改代码后仍出现视图无法弹出的问题,可筛选设备控制台中对应扩展Bundle ID的日志,若出现
_UIRemoteViewServiceViewController相关的生命周期报错,属于iOS 16.0早期版本的系统Bug,该问题在iOS 16.1正式版中已修复,不需要额外做兼容处理。
内容的提问来源于stack exchange,提问作者Sam Burkhard
相关产品推荐
相关产品推荐

