SwiftUI NavigationView尝试弹出缺失的目标(Monoceros?)

28

我的 Xcode 版本为 12,部署至 iOS 14.0。

  • 我的主屏幕拥有 NavigationView
  • 在 NavigationView 中有一个 TabView(包含 4 个选项卡)
  • 每个选项卡中都有包含按钮和 NavigationLinks 的子视图

应用程序的导航功能正常运行(当我点击子视图中的 NavigationLink 时,它会导航到正确的视图,当我点击返回按钮时,它会关闭该视图。)但是,当我点击返回按钮时,控制台会打印以下错误:

Trying to pop to a missing destination at /Library/Caches/com.apple.xbs/Sources/Monoceros/Monoceros-103/Shared/NavigationBridge_PhoneTV.swift:337

除了错误日志之外,应用程序功能正常,所以我计划现在忽略这个错误... 但是我想知道它的意思是什么?我的代码中没有任何名为“Monoceros”的内容。我猜测这与TabView是NavigationView的子视图有关?

编辑:

几个月后,这个问题仍然存在。下面是可重现的代码。打开ContentView(),在FirstScreen()上点击NavigationView,然后点击返回按钮。它会打印出Monoceros lol。

import SwiftUI

struct ContentView: View {
    var body: some View {
        NavigationView {
            TabView {
                FirstScreen()
                    .tabItem {
                        Text("One")
                        Image(systemName: "house.fill")
                    }
                
                Text("Second Screen")
                    .tabItem {
                        Text("Two")
                        Image(systemName: "heart.fill")
                    }
            }
        }
    }
}

struct FirstScreen: View {
    var body: some View {
        NavigationLink("Click here", destination: Text("Final Screen"))
        // Click the back button on FinalScreen prints:
        //Trying to pop to a missing destination at /Library/Caches/com.apple.xbs/Sources/Monoceros_Sim/Monoceros-120/Shared/NavigationBridge_PhoneTV.swift:341
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

你解决了吗? - Clément Tengip
4
不,我认为这是因为TabView是NavigationView的子视图。如果您将NavigationView作为TabView中的子视图添加,该错误就会消失。然而,这会改变UI并且对我们没有用。最终我们选择忽略错误并发布到App Store。据我所知,该错误并未引起任何问题。 - nicksarno
你能提供一个可重现的例子吗? - pawello2222
@pawello2222 已更新。谢谢。 - nicksarno
@nicksarno,你解决了被抛出的错误信息吗?我遇到了与你完全相同的问题...我不介意这个错误,但是在提交应用程序时不想被苹果拒绝! - Learn2Code
@Learn2Code 没有,但这不应该导致您被拒绝。 - nicksarno
2个回答

14

很遗憾,这是一个活跃的问题,涉及在NavigationView内部放置TabView

如果您将NavigationView放置在TabView内部,则不会出现错误,但这当然会导致选项卡从您的Final Screen中显示,这可能是您想要避免的。

                                      enter image description here

目前还没有解决此问题的方法,截至目前为止,我们需要等待Apple适当地实现TabViews的相应.navigationBarHidden()。

在将TabView嵌入到NavigationView中时,已经报告了问题和意外行为,但是如果您已经充分测试了应用程序并没有发现特别的问题,则可以安全地使用此方法。

或者,您将不得不手动构建一个TabView组件,如下所示:

import SwiftUI


enum Tab {
    case house, heart
}

struct TabView: View {
    @Binding var tabIdx: Tab
    
    var body: some View {
        HStack {
            Group {
                Spacer()
                
                Button (action: {
                    self.tabIdx = .house
                }) {
                    VStack{
                        Image(systemName: "house.fill")
                        Text("House")
                            .font(.system(size: 10))

                    }
                }
                .foregroundColor(self.tabIdx == .house ? .blue : .secondary)
                
                Spacer()
                
                Button (action: {
                    self.tabIdx = .heart
                }) {
                    VStack{
                        Image(systemName: "heart.fill")
                        Text("Heart")
                            .font(.system(size: 10))

                    }
                }
                .foregroundColor(self.tabIdx == .heart ? .blue : .secondary)
                
                Spacer()
            }
        }
        .padding(.bottom, 30)
        .padding(.top, 10)
        .background(Color(red: 0.1, green: 0.1, blue: 0.1))
        .font(.system(size: 30))
        .frame(height: 80)
    }
}

struct FirstScreen: View {
    var body: some View {
        NavigationLink("Click here", destination: Text("Final Screen"))
            .font(.system(size:20))
    }
}

struct ContentView: View {
    @State var tabIdx: Tab = .house
    
    var body: some View {
        NavigationView {
            VStack(spacing: 20) {
                Spacer()
                if tabIdx == .house {
                    FirstScreen()
                } else if tabIdx == .heart {
                    Text("Second Screen")
                }
                Spacer(minLength: 0)
                TabView(tabIdx: self.$tabIdx)
            }
            .ignoresSafeArea()

        }
    }

}

上述错误在这篇博客文章中详细说明,您可以参考该文章获取更多参考和示例。


这对我解决了问题。尽管我决定跟随另一个教程来创建自定义的tabView。https://www.youtube.com/watch?v=FxW9Dxt896U - codingCartooningCPA

0
2023年更新。显然NavigationView已经被弃用,你应该在iOS16中使用NavigationStack。只需将NavigationView更改为NavigationStack,警告就会消失!你仍然可以保留所有的导航链接。此外,通过这个更改,我的navigationTitle和navigationDisplayMode .inline在我的TabItems中开始起作用了。
struct ContentView: App {
@State var selection = 1

var body: some Scene {
WindowGroup {
    NavigationStack {
        TabView(selection: $selection) {
            GridView()
                .tabItem {
                    Label("Study", systemImage: "book")
                        .symbolRenderingMode(.hierarchical)
                }
                .tag(1)
            
            StudyView()
                .tabItem {
                    Label("Test", systemImage: "graduationcap")
                }
                .tag(2)
        }
        .navigationTitle(selection == 1 ? "Study a Language" : "Take a Test")
      }
   }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接