我正在嘗試將系結從父串列視圖傳遞到子詳細視圖。子詳細視圖包含編輯子的邏輯。我希望這些更改反映在父串列視圖中:
import SwiftUI
struct ParentListView: View {
var body: some View {
NavigationStack {
List {
ForEach(0 ..< 5) { number in
NavigationLink(value: number) {
Text("\(number)")
}
}
}
.navigationDestination(for: Int.self) { number in
ChildDetailView(number: number) //Cannot convert value of type 'Int' to expected argument type 'Binding<Int>'
}
}
}
}
struct ChildDetailView: View {
@Binding var number: Int
var body: some View {
VStack {
Text("\(number)")
Button {
number = 10
} label: {
Text("Add 10")
}
}
}
}
但正如您所見,我無法將數字傳遞給 ChildDetailView,因為它需要系結。我曾嘗試將 $ 放在數字之前,但這也不起作用。有沒有辦法讓這項作業,或者我使用新的 NavigationStack 完全錯誤?
uj5u.com熱心網友回復:
這可能是您正在尋找的解決方案。當您更改 ChildView 中的資料時,ParentView 中的資料也會更改。由于沒有你的包,我在 ParentView 中使用了不同的 NavigationView,但它是相同的邏輯。
當要在 ChildView 和 ParentView 之間傳遞資料時(用于小型作業),可以在 ChildView 中使用 @Binding 型別,在 ParentView 中使用 @State 型別。代碼:
import SwiftUI
struct ParentListView: View {
//Try this
@State var bindingData: Int = 0
var body: some View {
NavigationView {
List {
ForEach(0 ..< 5, id: \.self) { _ in
NavigationLink {
ChildDetailView(number: $bindingData) //Try this, and don't forget $ sign
} label: {
Text("\(bindingData)") //Try this
}
}
}
}
}
}
struct ChildDetailView: View {
@Binding var number: Int //Try this
var body: some View {
VStack {
Text("\(number)")
Button {
number = 10
} label: {
Text("Add 10")
}
}
}
}
uj5u.com熱心網友回復:
好吧,實際上這是可能的,但首先它需要事實源,即帶有要系結的資料的狀態,但在這種情況下,系結將只更新源,而不是目標。ObservableObject在這種情況下使用視圖模型更合適。
使用 Xcode 14 / iOS 16 測驗
注意:在這種情況下系結不會重繪 ChildDetailView- in 只能用于操作,但源已更新!
這是主要部分:
@State private var numbers = [1, 2, 3, 4, 5] // << data !!
var body: some View {
NavigationStack {
List {
ForEach($numbers) { number in // << binding !!
NavigationLink(value: number) {
Text("\(number.wrappedValue)")
}
}
}
.navigationDestination(for: Binding<Int>.self) { number in // << !!
ChildDetailView(number: number) // << binding !!
}
}
}
以及 Binding 通過導航鏈接值傳輸所需的幾個擴展。
GitHub上的完整代碼
uj5u.com熱心網友回復:
我們做到了!非常感謝各位大大的回答,幫了大忙!我整天都在為此苦苦掙扎
class NumbersService: ObservableObject {
@Published public var numbers = [1, 2, 3, 4, 5]
func incrementByTen(index: Int) {
numbers[index] = 10
}
}
struct ParentListView: View {
@StateObject var numbersService = NumbersService()
var body: some View {
NavigationStack {
List {
ForEach(numbersService.numbers.indices, id: \.self) { index in
NavigationLink(value: index) {
Text("\(numbersService.numbers[index])")
}
}
}
.navigationDestination(for: Int.self) { index in
ChildDetailView(index: index)
}
}
.environmentObject(numbersService)
}
}
struct ChildDetailView: View {
@EnvironmentObject var numbersService: NumbersService
var index: Int
var body: some View {
Group {
Text("\(numbersService.numbers[index])")
Button {
numbersService.incrementByTen(index: index)
} label: {
Text("Add 10")
}
}
}
}
基本上我只是使用了一個共享的 NumbersService,并通過索引識別了選定的數字。這樣,兩個視圖共享對正確數字的相同參考,并且值在 ParentView 和 ChildView 中都正確更新!我不確定這是否是太復雜的代碼,但它對我有用:P
uj5u.com熱心網友回復:
Apple 的 Foodtruck 示例應用程式有一個關于如何處理 navigationDestination 中的系結的示例。在他們的 github repo 中查看以下行
.navigationDestination(for: Donut.ID.self) { donutID in
DonutEditor(donut: model.donutBinding(id: donutID))
}
他們使用 Donut 模型 ID 進行導航。為了傳遞系結,他們在 FoodTruck 模型上添加了一個 getter/setter,其中包含一個甜甜圈串列,以通過 Donut.ID 生成一個系結。
public func donutBinding(id: Donut.ID) -> Binding<Donut> {
Binding<Donut> {
self.donuts[id]
} set: { newValue in
self.donuts[id] = newValue
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/489134.html
