如何从 SwiftUI 推送到现有的 UINavigationController 堆栈?

Posted

技术标签:

【中文标题】如何从 SwiftUI 推送到现有的 UINavigationController 堆栈?【英文标题】:How to push onto an existing UINavigationController stack from SwiftUI? 【发布时间】:2021-01-25 20:30:59 【问题描述】:

我们正在推动 SwiftUI 视图嵌入在 UIKit 土地中的 UIHostingViewController 中,如下所示:

首先制作UIViewController

    func hostingController() -> UIViewController 
    let swiftUIView = swiftUIView(viewModel: viewModel(data: [Data, Data, Data]))
    return UIHostingController(rootView: swiftUIView)

然后将其推入UINavigationView 堆栈:

[self.navigationController pushViewController:hostingViewController animated:YES];

这让我们进入SwiftUI 的环境。 但是,如果我们的SwiftUI 环境有它自己的导航堆栈,带有NavigationViewNavigationLink,那么原来的navigationBar 的后退按钮只能导航回原来的呈现UIViewController

有没有办法将嵌入在NavigationView 中的SwiftUI 视图推送到现有的UINavigationController 堆栈中?

到目前为止,我们唯一的想法是为每个新的SwiftUI 屏幕创建一个新的UIHostingViewController,并通过某种委托方法将其推入堆栈。

我们正在寻找的是这样的:

UINavigationStack: [UIViewController -> UIViewController -> SwiftUIView -> SwiftUIView]

navigationBar 中后面的 < 箭头将按预期运行。

如果我们可以进一步澄清,请告诉我们!

【问题讨论】:

【参考方案1】:

我遇到了类似的问题 - 我在 UIKit NavigationController 中添加了一个带有 NavigationView 的 SwiftUI 视图,当在 SwiftUI 视图中继续导航时会导致两层导航栏:UIKit NavigationController -> MyListNavigationView(MyListView) -> DetailView。

将 SwiftUI 视图添加到 UIKit NavigationController:

let swiftUIView = MyListNavigationView(content: contentList)
let hostingViewController =  UIHostingController(rootView: swiftUIView)
self.navigationController?.pushViewController(hostingViewController, animated: true)

我简化的 SwiftUI 视图(未验证它是否在简化后编译):

struct MyListNavigationView: View 
    @State var content: [String]
    var body: some View 
        NavigationView   //replace with Group 
            MyListView(content: $content)
                .toolbar 
                    ToolbarItem(placement: .navigationBarTrailing) 
                        NavigationLink 
                            DetailView(data: "New Data")
                         label: 
                            Image(systemName: "plus")
                        
                    
                
        
        .navigationViewStyle(.stack)
        .navigationTitle("My Title")
    


struct MyListView: View 
    @Binding var content: [String]
    var body: some View 
        List(content, id: \.self)  data in
            NavigationLink(destination: DetailsView(data: data)    
                MyRow(data: data)
            
        
    


struct MyRow: View 
    let data: String
    var body: some View 
        Text(data)
    


struct DetailView: View 
     let data: String
     var body: some View 
        Text(data)
    

因此,通过该设置,我有 2 层导航栏 - 只需进行简单的更改,这一切都对我有用: 由于我只将MyListNavigationView 添加到 UIKit NavigationController,因此我不需要独立的 SwiftUI NavigationView,只需将其替换为 Group - 我的 SwiftUI 视图中的所有导航/工具栏设置都已被父 UIKit NavigationController 采用而且只有一个导航栏。

【讨论】:

以上是关于如何从 SwiftUI 推送到现有的 UINavigationController 堆栈?的主要内容,如果未能解决你的问题,请参考以下文章

如何将现有的非空目录转换为 Git 工作目录并将文件推送到远程存储库

Git——如何从master检出分支dev并推送到远端?

如何在 SwiftUI 中将文本推送到边缘

text Git:将新的或现有的repo推送到Github

是否可以在 SwiftUI 中提供服务并将数据推送到视图并更新 UI?

在 SwiftUI 中,为啥 Spacer 会将文本推送到 TextEditor 框架之外?