我正在使用SwiftUI开发应用程序。该应用基于NavigationView
。
我正在使用提供UIKit
组件的第三方框架,并且该框架尚未更新为支持SwiftUI。
一种框架方法期望参数类型为UINavigationController
如何为SwiftUI创建的NavigationControlle
r提供此框架?或者如何创建UINavigationController
来取代SwiftUI的默认设置?
我阅读了https://developer.apple.com/tutorials/swiftui/interfacing-with-uikit和https://sarunw.com/posts/uikit-in-swiftui,但这些似乎解决了另一个问题:它们解释了如何在SwiftUI应用程序中使用UIKit组件。我的问题是相反的,我想使用SwiftUI App并访问基础的NavigationController对象。
答案 0 :(得分:2)
我认为您现在无法做到。看着NavigationView
的视图调试器,我得到下面的图像。
因此,您似乎必须采取另一种方法:
从UINavigationController
开始,然后将SwiftUI视图包装在UIHostingController
中。
答案 1 :(得分:1)
由于Yonat的解释,我了解如何做到这一点,这是我的解决方案,希望它能对其他人有所帮助。
第1部分:将在Swift UI中使用的UI View Controller。它调用第三方认证库,并传递UINavigationControler
作为参数。 UINavigationController
是一个空视图,正好在那里,以允许第三方身份验证库具有导航控制器来弹出“登录”屏幕。
struct LoginViewController: UIViewControllerRepresentable {
let navController = UINavigationController()
func makeUIViewController(context: Context) -> UINavigationController {
navController.setNavigationBarHidden(true, animated: false)
let viewController = UIViewController()
navController.addChild(viewController)
return navController
}
func updateUIViewController(_ pageViewController: UINavigationController, context: Context) {
}
func makeCoordinator() -> Coordinator {
return Coordinator(self)
}
class Coordinator: NSObject {
var parent: LoginViewController
init(_ loginViewController: LoginViewController) {
self.parent = loginViewController
}
}
func authenticate() {
let app = UIApplication.shared.delegate as! AppDelegate
let userData = app.userData
userData.authenticateWithDropinUI(navigationController: navController)
}
}
第2部分:Swift UI视图显示(空)UINavigationControler,并在其顶部覆盖一个SwiftUI视图。
import SwiftUI
struct LandingView: View {
@ObservedObject public var user : UserData
var body: some View {
let loginView = LoginViewController()
return VStack {
// .wrappedValue is used to extract the Bool from Binding<Bool> type
if (!$user.isSignedIn.wrappedValue) {
ZStack {
loginView
// build your welcome view here
Button(action: { loginView.authenticate() } ) {
UserBadge().scaleEffect(0.5)
}
}
} else {
// my main app view
// ...
}
}
}
}
答案 2 :(得分:0)
我试图做同样的事情,因为我想让InteractivePopGestureRecognizer在整个视图上都能工作。
我设法使用UINavigationController扩展并覆盖viewDidAppear来访问当前的导航控制器,检查是否启用了InteractivePopGestureRecognizer并对其进行了更改(https://stackoverflow.com/a/58068947/1745000)
最后,我的努力毫无意义。导航视图显示DetailHostingController时,它会关闭InteractivePopGestureRecognizer.isEnabled!
通过topViewController.view进行的托管视图确实包含私有类型SwiftUI.UIGestureRecognizer的手势识别器。尽管未设置目标...
最好嵌入传统的UINavigationController,因为导航视图自己的弹出手势无法取消(如果将视图拖动一点并停止,它会回弹然后关闭详细视图。