You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI中HomeList与SampleDataList间导航失败问题求助

问题描述

开发测试项目,目标实现从HomeList导航到SampleDataList,再根据URL文件类型跳转至不同视图,不使用Master/Detail模式。

运行代码时出现以下错误:

Note: Links search for destinations in any surrounding NavigationStack, then within the same column of a NavigationSplitView. A NavigationLink is presenting a value of type "URL" but there is no matching navigationDestination declaration visible from the location of the link. The link cannot be activated.

已尝试以下方案但均无效:

  • 将navigationDestination(for:destination:)移至HomeList中
  • 将SampleDataList嵌入NavigationStack
  • 使用NavigationPath(操作可能有误,未生效)

原代码

struct HomeList: View {
    
    var body: some View {
        NavigationStack {
            List {
                NavigationLink {
                    SampleDataList()
                } label: {
                    Text("Sample Data Picker")
                }
            }
        }
    }
}

extension URL: Identifiable {
    
    public var id: Int { self.hashValue }
    
}

struct SampleDataList: View {
    
    var urls: [URL] {
        let path = Bundle.main.resourcePath!
        let url = URL(fileURLWithPath: path).appendingPathComponent("SampleData")
        return try! FileManager.default.contentsOfDirectory(at: url, includingPropertiesForKeys: nil)
    }
    
    var body: some View {
        List(urls) { url in
            NavigationLink(value: url) {
                Text("\(url.lastPathComponent)")
            }
        }
        .listStyle(PlainListStyle())
        .navigationDestination(for: URL.self) { url in
            Text("\(url.lastPathComponent)")
        }
    }
}
解决方案

问题核心是导航目的地的作用域不匹配:使用value参数的NavigationLink需要对应的navigationDestination声明在其所在的顶层NavigationStack范围内,否则链路无法识别跳转目标。

修正方案(推荐)

将navigationDestination(for: URL.self)移至顶层NavigationStack内部,确保整个导航栈能识别URL类型的跳转:

struct HomeList: View {
    var body: some View {
        NavigationStack {
            List {
                NavigationLink {
                    SampleDataList()
                } label: {
                    Text("Sample Data Picker")
                }
            }
            // 将导航目的地声明放在顶层NavigationStack内
            .navigationDestination(for: URL.self) { url in
                Text("\(url.lastPathComponent)")
            }
        }
    }
}

extension URL: Identifiable {
    // 替换hashValue为absoluteString,避免ID碰撞风险
    public var id: String { self.absoluteString }
}

struct SampleDataList: View {
    var urls: [URL] {
        let path = Bundle.main.resourcePath!
        let url = URL(fileURLWithPath: path).appendingPathComponent("SampleData")
        return try! FileManager.default.contentsOfDirectory(at: url, includingPropertiesForKeys: nil)
    }
    
    var body: some View {
        List(urls) { url in
            NavigationLink(value: url) {
                Text("\(url.lastPathComponent)")
            }
        }
        .listStyle(PlainListStyle())
        // 移除此处的navigationDestination
    }
}

补充说明

  • 原URL的Identifiable扩展用hashValue作为id存在碰撞风险,改用absoluteString能保证ID唯一。
  • 若坚持在SampleDataList内声明navigationDestination,需给SampleDataList单独嵌套NavigationStack,但这种方式会形成嵌套导航栈,仅在特定场景下适用。

内容的提问来源于stack exchange,提问作者DanubePM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 19:45:34