SwiftUI与UIKit混合开发:如何用UINavigationController导航?
解决SwiftUI与UIKit混合导航的双导航栏问题
当然可以在SwiftUI中继续使用UIKit的UINavigationController进行导航,这恰恰是解决你当前双导航栏问题的有效方案之一。下面分两种思路给出具体实现:
方案一:直接复用UIKit的UINavigationController跳转
这种方式完全沿用你熟悉的UIKit导航逻辑,避免SwiftUI导航组件和UIKit导航栏冲突:
给SwiftUI视图传递导航控制器引用
先定义一个环境键,用来在SwiftUI环境中存储UIKit的导航控制器:private struct NavigationControllerKey: EnvironmentKey { static let defaultValue: UINavigationController? = nil } extension EnvironmentValues { var navigationController: UINavigationController? { get { self[NavigationControllerKey.self] } set { self[NavigationControllerKey.self] = newValue } } }在UIKit中跳转到
SignUpView时,把当前的UINavigationController注入到SwiftUI环境:let signUpView = SignUpView() .environment(\.navigationController, self.navigationController) let hostingVC = UIHostingViewController(rootView: signUpView) self.navigationController?.pushViewController(hostingVC, animated: true)在SwiftUI视图中触发跳转
在SignUpView里通过环境获取导航控制器,直接push包裹VerifyOTPView的UIHostingViewController:struct SignUpView: View { @Environment(\.navigationController) private var navController var body: some View { Button("前往OTP验证") { let verifyView = VerifyOTPView() .environment(\.navigationController, navController) let hostingVC = UIHostingViewController(rootView: verifyView) navController?.pushViewController(hostingVC, animated: true) } } }
方案二:隐藏SwiftUI导航栏,复用UIKit导航栏
如果你更倾向于使用SwiftUI的NavigationStack语法,可以通过隐藏SwiftUI自身的导航栏,让UIKit的导航栏主导:
struct SignUpView: View { var body: some View { NavigationStack { VStack(spacing: 20) { NavigationLink("前往OTP验证", destination: VerifyOTPView()) } .navigationBarHidden(true) // 隐藏SwiftUI的导航栏,避免双栏 .toolbar { // 这里的toolbar内容会映射到UIKit的导航栏上 ToolbarItem(placement: .principal) { Text("账号注册") } } } } }
这种方式既保留了SwiftUI的导航语法,又不会出现双导航栏的问题,同时还能通过toolbar配置UIKit导航栏的元素。
两种方案各有侧重:方案一适合习惯UIKit导航逻辑的开发者,完全沿用原有经验;方案二适合逐步过渡到SwiftUI的场景,兼顾SwiftUI的语法特性。
内容的提问来源于stack exchange,提问作者Mrugesh Tank
相关产品推荐
相关产品推荐

