在初始化期间确定 NavigationLink 目标
Determine NavigationLink Destination During Initialization
我正在尝试根据提供给视图的通用数据在 init()
内动态确定 SwiftUI NavigationLink
的目的地。
根据下面的代码,如果 Item
是 Tour
,目标应该是 TourDetailView
,否则是 LocationDetailView
。
struct CardView<Item: CardItem>: View {
let card: Item
private let destination: T
init(card: Item) {
self.card = card
if Item.self == Tour.self {
destination = TourDetailView(tour: card as! Tour) as! T
} else {
destination = LocationDetailView(location: card as! Location) as! T
}
}
var body: some View {
NavigationLink(destination: destination) {
...
}
}
}
目前代码未编译,因为 T
未定义。如果我将 T
定义为:
struct CardView<Item: CardItem, T: View>: View {
CardView
已处理,但随后我必须编辑调用 CardView 的视图,这都会引入不必要的复杂性,最终我必须在 @main
中定义 T,这是不允许的。
我怎样才能达到我想要的?我试图让 destination
成为另一种类型,但没有成功。
这里有一个简单的演示来解决您的问题。只需将视图存储在 属性 中,类型为 AnyView
。
struct ContentView: View {
let destination: AnyView
init() {
// This is just demo purpose, here comes your condition
if false {
destination = AnyView(DetailViewA())
} else {
destination = AnyView(DetailViewB())
}
}
var body: some View {
NavigationView {
NavigationLink(
destination: destination,
label: {
Text("Navigate")
})
}
}
}
struct DetailViewA: View {
var body: some View {
Text("A")
}
}
struct DetailViewB: View {
var body: some View {
Text("B")
}
}
我正在尝试根据提供给视图的通用数据在 init()
内动态确定 SwiftUI NavigationLink
的目的地。
根据下面的代码,如果 Item
是 Tour
,目标应该是 TourDetailView
,否则是 LocationDetailView
。
struct CardView<Item: CardItem>: View {
let card: Item
private let destination: T
init(card: Item) {
self.card = card
if Item.self == Tour.self {
destination = TourDetailView(tour: card as! Tour) as! T
} else {
destination = LocationDetailView(location: card as! Location) as! T
}
}
var body: some View {
NavigationLink(destination: destination) {
...
}
}
}
目前代码未编译,因为 T
未定义。如果我将 T
定义为:
struct CardView<Item: CardItem, T: View>: View {
CardView
已处理,但随后我必须编辑调用 CardView 的视图,这都会引入不必要的复杂性,最终我必须在 @main
中定义 T,这是不允许的。
我怎样才能达到我想要的?我试图让 destination
成为另一种类型,但没有成功。
这里有一个简单的演示来解决您的问题。只需将视图存储在 属性 中,类型为 AnyView
。
struct ContentView: View {
let destination: AnyView
init() {
// This is just demo purpose, here comes your condition
if false {
destination = AnyView(DetailViewA())
} else {
destination = AnyView(DetailViewB())
}
}
var body: some View {
NavigationView {
NavigationLink(
destination: destination,
label: {
Text("Navigate")
})
}
}
}
struct DetailViewA: View {
var body: some View {
Text("A")
}
}
struct DetailViewB: View {
var body: some View {
Text("B")
}
}