【问题标题】:SwiftUI 4.0 - Passing a Binding via .navigationDestination(for: , destination: )SwiftUI 4.0 - 通过 .navigationDestination(for: , destination: ) 传递绑定
【发布时间】:2022-11-06 10:15:35
【问题描述】:

如何通过新的 .navigationDestination(for: , destination: ) 传递绑定?

import SwiftUI

enum TestEnum: String, Hashable, CaseIterable {
    case first, second, third
}

struct ContentView: View {
    
    @State private var test: TestEnum = .first

    var body: some View {
        NavigationStack {
            VStack {
                NavigationLink(value: test, label: {
                    Text(test.rawValue)
                })
            }
            // This does not work, as it won't allow me to use $caze
            .navigationDestination(for: TestEnum.self, destination: { caze in
                SecondView(test: $caze)
            })
        }
    }
}

struct SecondView: View {
    
    @Environment(\.presentationMode) var presentationMode
    @Binding var test: TestEnum
    
    var body: some View {
        ForEach(TestEnum.allCases, id: \.self) { caze in
            Button(action: {
                test = caze
                presentationMode.wrappedValue.dismiss()
            }, label: {
                Text(caze.rawValue)
            })
        }
    }
}

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

在 SwiftUI 3.0 中,我只需使用:

NavigationLink(destination: SecondView(test: $test), label: {
   Text(test.rawValue)
})

这仍然是正确的方法吗,因为我们还不能通过绑定?

对使用 EnvironmentObject 和传递索引等复杂的解决方法并不真正感兴趣,因为 SwiftUI 3.0 方法可以正常工作。

但是,如果有通过 .navigationDestination(for: , destination: ) 传递绑定的正确方法,我会很乐意使用它。

【问题讨论】:

  • 我认为将NavigationLink(destination: SecondView(test: $test), label: { Text(test.rawValue) })NavigationStack 一起使用而不是navigationDestination 并没有错。 NavigationView 已弃用,但 NavigationLink(destination: ..) 已弃用
  • 没有“正确”的方式不是您现在使用的方式。 Binding 不是 Hashable

标签: swift swiftui swiftui-navigationlink swiftui-navigationstack


【解决方案1】:

根据这个文档:

https://developer.apple.com/documentation/charts/chart/navigationdestination(for:destination:)/

从 NavigationLink 传递目的地的位置,但在文档中,他们使用 NavigationLink("Mint", value: Color.mint) 版本的 NavigationLink。我不知道这是否有什么不同。

您正在使用 NavigationLink(value:label:)

编辑:经过进一步调查,我坚持认为您使用的 ViewModifier 错误。

阅读我上面指出的文档。 viewModifier 签名是:

func navigationDestination<D, C>(
    for data: D.Type,
    destination: @escaping (D) -> C
) -> some View where D : Hashable, C : View

所以,当你通过$凯兹你没有通过上面的@State var,但是NavigationLink(值:测试...那不是@State 包装器。通用 D ... 是单个值,所以 $caze 不是对状态的绑定。

您可以正常通过 $test,这是对 State 测试的绑定。但是闭包内的参数 .navigationDestination( value in ... 不是。

【讨论】:

  • 您的回答与问题完全无关。此外,NavigationLink("", value:) 是 NavigationLink(value:label:) 的简化版本。前者有一个简单的文本,后者可以是 NavigationLink 标签的复杂视图。
  • 很抱歉试图回答你。我尽力了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-10-17
  • 2023-01-24
  • 2017-11-26
  • 2022-01-06
  • 2014-09-18
  • 2017-03-24
  • 2011-05-12
相关资源
最近更新 更多