chr*_*ags 3 swiftui swiftui-navigationlink
尝试以编程方式触发导航链接时遇到上述错误的问题。单击链接后,错误的目标数组元素将偶尔加载(相对于单击的标签),当然会显示上述错误。
当我以非编程方式触发导航链接时,不会发生错误,但当用户单击此链接时,我需要运行另一种方法。
我已经阅读了几个问题,例如此处和此处,但找不到我的案例的原因。
模型结构:
struct Place: Identifiable {
var id: UUID = UUID()
var name: String = ""
var testBool: Bool = false
Run Code Online (Sandbox Code Playgroud)
}
环境对象的类:(生产项目有许多属性和方法 - 本质上这是 ViewModel)
class UserPlaces: ObservableObject {
@Published var placesArray: [Place] = [Place]([Place(name: "Christian", testBool: false),Place(name: "Catherine", testBool: true)])
Run Code Online (Sandbox Code Playgroud)
}
导航布尔类:(生产项目这里有许多属性,我想将它们保留在一个类中)
class Navigation: ObservableObject {
@Published var showPlaceDetail: Bool = false
Run Code Online (Sandbox Code Playgroud)
}
ContentView:(NavigationView所在的父视图)
import SwiftUI
Run Code Online (Sandbox Code Playgroud)
结构ContentView:视图{
var body: some View {
NavigationView {
ScrollView {
Text("Hello, world!")
.padding()
CardsGrid2()
} // End ScrollView
} // End Navigation View
} // End body
Run Code Online (Sandbox Code Playgroud)
} // 结束结构
CardsGrid:(在此视图中,NavigationLink 不是以编程方式触发的,并且不会显示控制台错误。)
import SwiftUI
Run Code Online (Sandbox Code Playgroud)
struct CardsGrid: View { @EnvironmentObject var userPlaces: UserPlaces
var gridLayout: [GridItem] = [GridItem(.flexible(minimum: 40), spacing: -36),GridItem(.flexible(minimum: 40), spacing: -36)]
var body: some View {
LazyVGrid(columns: gridLayout, spacing: 10) {
ForEach(userPlaces.placesArray) { placeCard in
NavigationLink(
destination: Text("Destination")
, label: { Text("Label") }
)
} // End ForEach
} // End LazyVGrid
} // End body
Run Code Online (Sandbox Code Playgroud)
} // 结束结构
CardsGridProgrammatic:(在此视图中,NavigationLink 以编程方式触发,并显示控制台错误。)
import SwiftUI
Run Code Online (Sandbox Code Playgroud)
结构 CardsGridProgrammatic: 查看 {
@EnvironmentObject var userPlaces: UserPlaces
@EnvironmentObject var navigation: Navigation
var gridLayout: [GridItem] = [GridItem(.flexible(minimum: 40), spacing: -36),GridItem(.flexible(minimum: 40), spacing: -36)]
var body: some View {
LazyVGrid(columns: gridLayout, spacing: 10) {
ForEach(userPlaces.placesArray) { placeCard in
NavigationLink(destination: Text("Destination"), isActive: $navigation.showPlaceDetail) { EmptyView() }
.isDetailLink(false)
Button(action: {
navigation.showPlaceDetail = true
// Other required method call here
}, label: { Text("label") })
} // End ForEach
} // End LazyVGrid
} // End body
Run Code Online (Sandbox Code Playgroud)
} // 结束结构
此外:
我怎样才能解决这个问题?
正如您的链接建议的那样,NavigationLink将ForEach. 以下内容对我来说在 macos 12.01、xcode 13.1、目标 ios 15 和 macCatalyst 12 上运行良好。在 mac Monterey 和 iPhone ios 15 设备上进行了测试。在旧系统上可能有所不同。可以肯定的是,这是我用于测试的代码:
import SwiftUI
@main
struct TestApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
struct Place: Identifiable {
var id: UUID = UUID()
var name: String = ""
var testBool: Bool = false
}
class UserPlaces: ObservableObject {
@Published var placesArray: [Place] = [
Place(name: "Christian", testBool: false),
Place(name: "Catherine", testBool: true)]
}
class Navigation: ObservableObject {
@Published var showPlaceDetail: Bool = false
}
struct ContentView: View {
@StateObject var userPlaces = UserPlaces()
@StateObject var navigation = Navigation()
var body: some View {
NavigationView {
ScrollView {
Text("Hello, world!").padding()
CardsGrid()
}
}
.environmentObject(userPlaces)
.environmentObject(navigation)
}
}
struct CardsGrid: View {
@EnvironmentObject var userPlaces: UserPlaces
@EnvironmentObject var navigation: Navigation
@State var selection: Place? // <--- here
var gridLayout: [GridItem] = [GridItem(.flexible(minimum: 40), spacing: -36),
GridItem(.flexible(minimum: 40), spacing: -36)]
var body: some View {
LazyVGrid(columns: gridLayout, spacing: 10) {
ForEach(userPlaces.placesArray) { placeCard in
Button(action: {
selection = placeCard // <--- here
navigation.showPlaceDetail = true
// Other required method call here
}, label: { Text("\(placeCard.name) label") })
}
}
// --- here
NavigationLink(destination: Text("Destination \(selection?.name ?? "")"),
isActive: $navigation.showPlaceDetail) { EmptyView() }.isDetailLink(false)
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1873 次 |
| 最近记录: |