SwiftUI NavigationView 尝试弹出到丢失的目的地(Monoceros?)

问题描述 投票:0回答:2

我正在使用 Xcode 12 进行 iOS 14.0 部署。

  • 我的主屏幕有一个导航视图
  • NavigationView 中有一个 TabView(有 4 个选项卡)
  • 每个选项卡内都有带有按钮和导航链接的子视图

应用程序上的导航功能正常(当我单击其中一个子视图上的 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() 上单击 NavigationLink,然后单击后退按钮。它会打印出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()
    }
}
swift xcode swiftui navigationview swiftui-navigationlink
2个回答
13
投票

不幸的是,这是一个活跃的问题,

TabView
放置在
NavigationView
内。

如果您将

NavigationView
放置在
TabView
内,则该错误不会自行显现,但这当然会导致选项卡从您的
Final Screen
内显示,您可能想避免这种情况。

                                      

目前还没有解决此问题的方法,到目前为止,我们还需要等待 Apple 正确实现 TabView 的相应

.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()

        }
    }

}

上述错误在this博客文章中有详细说明,您可以查阅该文章以获取进一步的参考和更多示例。


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")
      }
   }
}
© www.soinside.com 2019 - 2024. All rights reserved.