如何在UIKit的UIHostingController承载的SwiftUI视图中使用navigationDestination
方法1:将SwiftUI视图嵌入NavigationStack中
navigationDestination是SwiftUI NavigationStack专属的导航API,无法直接与UIKit的UINavigationController联动。你可以把目标SwiftUI视图包裹在NavigationStack里,再交给UIHostingController,同时隐藏UIKit的导航栏避免双重导航栏冲突:
// UIKit Part let rootSwiftUIView = NavigationStack { MySwiftUIView() } let hostingController = UIHostingController(rootView: rootSwiftUIView) // 隐藏UIKit导航栏,使用SwiftUI的NavigationStack导航栏 hostingController.navigationItem.hidesBackButton = true navigationController?.pushViewController(hostingController, animated: true) // SwiftUI Part struct MySwiftUIView: View { @State private var isPresented = false var body: some View { VStack { Button("Navigate") { isPresented = true } .navigationDestination(isPresented: $isPresented) { Text("New View") .navigationTitle("Detail") } } .navigationTitle("Home") } }
方法2:通过回调让UIKit处理导航
如果不想引入SwiftUI的NavigationStack,可以在SwiftUI视图中定义回调闭包,触发时通知UIKit侧push新的视图控制器:
// UIKit Part let hostingController = UIHostingController(rootView: MySwiftUIView(onNavigate: { let detailHostingController = UIHostingController(rootView: Text("New View")) navigationController?.pushViewController(detailHostingController, animated: true) })) navigationController?.pushViewController(hostingController, animated: true) // SwiftUI Part struct MySwiftUIView: View { let onNavigate: () -> Void var body: some View { VStack { Button("Navigate") { onNavigate() } } .navigationTitle("Home") } }
方法3:使用UIViewControllerRepresentable桥接导航逻辑
如果需要更灵活的跨框架导航交互,可以自定义桥接组件,让SwiftUI能直接调用UIKit的导航能力:
// 桥接组件 struct NavigationBridge: UIViewControllerRepresentable { let navigationController: UINavigationController func makeUIViewController(context: Context) -> UIViewController { UIViewController() } func updateUIViewController(_ uiViewController: UIViewController, context: Context) {} static func dismantleUIViewController(_ uiViewController: UIViewController, coordinator: Coordinator) {} // 定义push方法 func push<Content: View>(_ view: Content, animated: Bool = true) { let hostingController = UIHostingController(rootView: view) navigationController.pushViewController(hostingController, animated: animated) } // 注入SwiftUI环境的Modifier struct Provider: ViewModifier { let navigationBridge: NavigationBridge func body(content: Content) -> some View { content.environment(\.navigationBridge, navigationBridge) } } } // 扩展环境变量 extension EnvironmentValues { var navigationBridge: NavigationBridge? { get { self[NavigationBridgeKey.self] } set { self[NavigationBridgeKey.self] = newValue } } } private struct NavigationBridgeKey: EnvironmentKey { static let defaultValue: NavigationBridge? = nil } // 使用示例 // UIKit Part guard let navController = navigationController else { return } let bridge = NavigationBridge(navigationController: navController) let rootView = MySwiftUIView().modifier(NavigationBridge.Provider(navigationBridge: bridge)) let hostingController = UIHostingController(rootView: rootView) navController.pushViewController(hostingController, animated: true) // SwiftUI Part struct MySwiftUIView: View { @Environment(\.navigationBridge) private var navigationBridge var body: some View { VStack { Button("Navigate") { navigationBridge?.push(Text("New View")) } } .navigationTitle("Home") } }
内容的提问来源于stack exchange,提问作者yzoldan
相关产品推荐
相关产品推荐

