---- 更新以提供可重現的示例 ----
以下是我的視圖檔案。我想讓每個導航鏈接目標鏈接到存盤在字典中的視圖模型(在示例中由一個簡單的字串表示)。
但是,以下代碼不起作用,并且每個專案始終不顯示任何內容,即使我嘗試了SwiftUI NavigationLink 中的解決方案,它會立即加載目標視圖,而無需單擊
struct ContentView: View {
private var indices: [Int] = [1, 2, 3, 4]
@State var strings: [Int: String] = [:]
var body: some View {
NavigationView {
List {
ForEach(indices, id: \.self) { index in
NavigationLink {
NavigationLazyView(view(for: index))
} label: {
Text("\(index)")
}
}
}
.onAppear {
indices.forEach { index in
strings[index] = "Index: \(index)"
}
print(strings.keys)
}
}
}
@ViewBuilder
func view(for index: Int) -> some View {
if let str = strings[index] {
Text(str)
}
}
}
struct NavigationLazyView<Content: View>: View {
let build: () -> Content
init(_ build: @autoclosure @escaping () -> Content) {
self.build = build
}
var body: Content {
build()
}
}
uj5u.com熱心網友回復:
您正在與 SwiftUI 的幾個負責人合作,這足以讓事情變得糟糕。通過一些調整,您甚至不需要惰性導航鏈接。
首先,通常在 SwiftUI 中,建議不要在其中使用索引ForEach——它很脆弱并且可能導致崩潰,更重要的是,如果專案發生更改,視圖不知道更新,因為它只比較索引(如果陣列保持相同的大小,永遠不會改變)。
通常,最好Identifiable使用ForEach.
例如,這可以正常作業:
struct Item : Identifiable {
var id = UUID()
var index: Int
var string : String?
}
struct ContentView: View {
private var indices: [Int] = [1, 2, 3, 4]
@State var items: [Item] = []
var body: some View {
NavigationView {
List(items) { item in
NavigationLink {
view(for: item)
} label: {
Text("\(item.index)")
}
}
.onAppear {
items = indices.map { Item(index: $0, string: "Index: \($0)")}
}
}
}
@ViewBuilder
func view(for item: Item) -> some View {
Text(item.string ?? "Empty")
}
}
我不能絕對肯定地說你的第一個例子發生了什么,以及為什么懶惰的導航鏈接不能解決它,但我的理論是,view(for:)并且strings正在被捕獲,@autoclosure因此在鏈接時沒有反映它們的更新值實際上是建造的。@State由于上述使用不可識別索引的問題List,這是設定變數時串列未實際更新的副作用。ForEach
我假設您的實際情況足夠復雜,因此有充分的理由在模型中進行突變onAppear并將索引與模型分開,但為了以防萬一,為了清楚和完整,以下將是一個更簡單的解決方案對于這個問題,如果它真的是一個簡單的情況:
struct ContentView: View {
private var items: [Item] = [.init(index: 1, string: "Index 1"),.init(index: 2, string: "Index 2"),.init(index: 3, string: "Index 3"),.init(index: 4, string: "Index 4"),]
var body: some View {
NavigationView {
List(items) { item in
NavigationLink {
view(for: item)
} label: {
Text("\(item.index)")
}
}
}
}
@ViewBuilder
func view(for item: Item) -> some View {
Text(item.string ?? "Empty")
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/429701.html
上一篇:如何從父母委托給多個不同的孩子?
下一篇:如何模擬協議的通用實作?
