Xcode报错:A NavigationLink is presenting a value of type “Int” but there is no matching navigationDestination declaration visible from the location of the link. The link cannot be activated.
Xcode报错:A NavigationLink is presenting a value of type “Int” but there is no matching navigationDestination declaration visible from the location of the link. The link cannot be activated.

Xcode报错:A NavigationLink is presenting a value of type “Int” but there is no matching navigationDestination declaration visible from the location of the link. The link cannot be activated.

问题描述

在练习NavigationLink和NavigationDestination跳转页面时,Xcode预览界面中点击NavigationLink,发现跳转到对应页面后,马上跳回原来的页面。

同时,在使用预览的过程中,Xcode没有报错。

运行模拟器,在点击NavigationLink后,发现Xcode存在如下报错:

A NavigationLink is presenting a value of type “Int” but there is no matching navigationDestination declaration visible from the location of the link. The link cannot be activated.

Note: Links search for destinations in any surrounding NavigationStack, then within the same column of a NavigationSplitView.

解决问题

经过排查发现原因为,ContentView 和 PersonDetailView 中分别创建了自己的 NavigationStack,导致导航堆栈被重置。

在 SwiftUI 中,导航堆栈应该是整个导航流程的“全局容器”。如果在一个视图内创建了新的 NavigationStack,那么导航上下文会被覆盖或重置,导致跳转后立即返回到上一个视图。

解决方案为

只在根视图(ContentView)中使用一个 NavigationStack,而在子视图(PersonDetailView)中直接布局内容,而不是再创建新的 NavigationStack。

删除PersonDetailView的NavigationStack代码

// PersonDetailView
var body: some View {
    // NavigationStack {    删除子视图的NavigationStack
        List(adults) { user in
            HStack {
                Text("姓名:\(user.name),")
                Text("年龄:\(user.age)")
            }
        }
    // }
}

问题得到解决

完整代码

ContextView文件

import SwiftUI
import SwiftData

struct ContentView: View {
    @Environment(\.modelContext) private var context
    @Query var adults: [Person]
    @State private var selectAge: Int = 18
    var body: some View {
        NavigationStack {
            VStack {
                // 列表展示查询结果
                List {
                    Section("人员名单") {
                        ForEach(adults, id: \.self) { person in
                            Text("\(person.name),年龄:\(person.age)")
                        }
                    }
                }
                .frame(height: 330) // 限制列表的高度
                VStack {
                    Text("筛选结果页面(比如年龄大于 \(selectAge) 的人员)")
                    Picker("选择年龄", selection: $selectAge) {
                        ForEach(1...100, id: \.self) { age in
                            Text("\(age)").tag(age)
                        }
                    }
                    .pickerStyle(WheelPickerStyle())
                    NavigationLink(value:selectAge) {
                        Text("查询")
                            .frame(maxWidth: 300)
                            .padding()
                            .background(Color.blue)
                            .foregroundColor(.white)
                            .cornerRadius(10)
                    }
                }
                Spacer()
            }
            .navigationTitle("列表")
            .navigationDestination(for: Int.self) { age in
                PersonDetailView(age: age)
            }
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    Button("添加测试数据") {
                        try? context.delete(model: Person.self)
                        context.insert(Person(name: "李四", age: 7))
                        context.insert(Person(name: "章三", age: 58))
                        context.insert(Person(name: "王五", age: 24))
                        context.insert(Person(name: "北方", age: 47))
                        context.insert(Person(name: "卫子夫", age: 15))
                        context.insert(Person(name: "鸥玉", age: 35))
                    }
                }
            }
        }
    }
}

#Preview {
    ContentView()
        .modelContainer(for: Person.self)
}

PersonDetailView文件

import SwiftUI
import SwiftData

struct PersonDetailView: View {
    @Environment(\.modelContext) private var context
    @Query var adults: [Person]
    
    init(age: Int) {
        _adults = Query(filter: #Predicate<Person> {
            $0.age > age
        })
    }
    var body: some View {
        List(adults) { user in
            HStack {
                Text("姓名:\(user.name),")
                Text("年龄:\(user.age)")
            }
        }
    }
}

#Preview {
    PersonDetailView(age:0)
        .modelContainer(for: Person.self)
}

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开放者。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注