使用 ForEach 在 SwiftUI 中选择时,有没有办法更改 tabItem 的图像?
Is there a way to change a tabItem's image when selected in SwiftUI when using ForEach?
考虑 SwiftUI 中最简单的选项卡视图应用程序:
struct ContentView: View {
@State private var selection = 0
var body: some View {
TabView(selection: $selection){
Text("First View")
.font(.title)
.tabItem {
VStack {
Image("first")
Text("First")
}
}
.tag(0)
Text("Second View")
.font(.title)
.tabItem {
VStack {
Image("second")
Text("Second")
}
}
.tag(1)
}
}
}
只要点击一个选项卡,就会重新加载选项卡项目,如果需要,您可以通过将选择与标签进行比较来更改所选选项卡的图像。但是,如果您在变量中有动态数量的选项卡并使用 ForEach
来显示它们,那将不起作用:
struct ContentView: View {
@State private var selection = 0
private var items: [AnyView] {
return [
AnyView(Text("First View")
.font(.title)
.tabItem {
VStack {
Image("first1")
Text("First1")
}
}
.tag(0)),
AnyView(Text("Second View")
.font(.title)
.tabItem {
VStack {
Image("second")
Text("Second")
}
}
.tag(1))
]
}
var body: some View {
TabView(selection: $selection){
ForEach(0..<self.items.count) { index in
self.items[index]
}
}
}
}
ForEach
的主体在视图重新加载时不会被调用。有没有办法在您的 TabView 中使用 ForEach
来完成更改图像?
尝试以下操作:
struct ContentView: View {
@State private var selection = 0
var body: some View {
TabView(selection: $selection){
Text("First View")
.font(.title)
.tabItem {
VStack {
Image(systemName: selection == 0 ? "xmark" : "plus")
Text("First")
}
}
.tag(0)
Text("Second View")
.font(.title)
.tabItem {
VStack {
Image(systemName: selection == 1 ? "xmark" : "minus")
Text("Second")
}
}
.tag(1)
}
}
}
答案在文档中!使用具有范围的 ForEach 时:
/// Creates an instance that computes views on demand over a *constant*
/// range.
///
/// This instance only reads the initial value of `data` and so it does not
/// need to identify views across updates.
///
/// To compute views on demand over a dynamic range use
/// `ForEach(_:id:content:)`.
因此,要实现此功能,请使用 ForEach(_:id:content:)
。
考虑 SwiftUI 中最简单的选项卡视图应用程序:
struct ContentView: View {
@State private var selection = 0
var body: some View {
TabView(selection: $selection){
Text("First View")
.font(.title)
.tabItem {
VStack {
Image("first")
Text("First")
}
}
.tag(0)
Text("Second View")
.font(.title)
.tabItem {
VStack {
Image("second")
Text("Second")
}
}
.tag(1)
}
}
}
只要点击一个选项卡,就会重新加载选项卡项目,如果需要,您可以通过将选择与标签进行比较来更改所选选项卡的图像。但是,如果您在变量中有动态数量的选项卡并使用 ForEach
来显示它们,那将不起作用:
struct ContentView: View {
@State private var selection = 0
private var items: [AnyView] {
return [
AnyView(Text("First View")
.font(.title)
.tabItem {
VStack {
Image("first1")
Text("First1")
}
}
.tag(0)),
AnyView(Text("Second View")
.font(.title)
.tabItem {
VStack {
Image("second")
Text("Second")
}
}
.tag(1))
]
}
var body: some View {
TabView(selection: $selection){
ForEach(0..<self.items.count) { index in
self.items[index]
}
}
}
}
ForEach
的主体在视图重新加载时不会被调用。有没有办法在您的 TabView 中使用 ForEach
来完成更改图像?
尝试以下操作:
struct ContentView: View {
@State private var selection = 0
var body: some View {
TabView(selection: $selection){
Text("First View")
.font(.title)
.tabItem {
VStack {
Image(systemName: selection == 0 ? "xmark" : "plus")
Text("First")
}
}
.tag(0)
Text("Second View")
.font(.title)
.tabItem {
VStack {
Image(systemName: selection == 1 ? "xmark" : "minus")
Text("Second")
}
}
.tag(1)
}
}
}
答案在文档中!使用具有范围的 ForEach 时:
/// Creates an instance that computes views on demand over a *constant*
/// range.
///
/// This instance only reads the initial value of `data` and so it does not
/// need to identify views across updates.
///
/// To compute views on demand over a dynamic range use
/// `ForEach(_:id:content:)`.
因此,要实现此功能,请使用 ForEach(_:id:content:)
。