Reputation: 1855
In the current code when a text item is clicked the pageIndex gets updated but the UI doesn't react to the change
ForEach(T2Array) { ele in
Text(ele.name)
.foregroundColor(ele.isSelected ? Color.blue : Color.black)
.onTapGesture {
print(pageIndex)
pageIndex = 4
print(pageIndex)
}
}
The same code but when the ForEach syntax is used in a different way it works, why is its happening
ForEach(0...T2Array.count-1,id:\.self) { i in
Text(T2Array[i].name)
.foregroundColor(T2Array[i].isSelected ? Color.blue : Color.black)
.onTapGesture {
print(pageIndex)
pageIndex = 4
print(pageIndex)
}
}
Full code
import SwiftUI
struct T1Object:Identifiable{
let id = UUID()
var isSelected = false
let name:String
}
struct T1:View{
@State var T1Array:[T1Object] = [
T1Object(isSelected: true, name: "Albin"),
T1Object(isSelected: false, name: "Albin2"),
T1Object(isSelected: false, name: "Albin3"),
T1Object(isSelected: false, name: "Albin4"),
T1Object(isSelected: false, name: "Albin5"),
T1Object(isSelected: false, name: "Albin6"),
]
@State var pageIndex:Int = 0
var body: some View {
VStack{
T2(T2Array: $T1Array,pageIndex:$pageIndex)
Text("selected Index:\(pageIndex)")
}
}
}
struct T2:View{
@Binding var T2Array:[T1Object]
@Binding var pageIndex:Int
var body: some View {
TabView(selection: $pageIndex) {
//This doesnt work
ForEach(T2Array) { ele in
Text(ele.name)
.foregroundColor(ele.isSelected ? Color.blue : Color.black)
.onTapGesture {
print(pageIndex)
pageIndex = 4
print(pageIndex)
}
}
//..................
//This commented code works fine why?
//..................
// ForEach(0...T2Array.count-1,id:\.self) { i in
// Text(T2Array[i].name)
// .foregroundColor(T2Array[i].isSelected ? Color.blue : Color.black)
// .onTapGesture {
// print(pageIndex)
// pageIndex = 4
// print(pageIndex)
// }
// }
}.tabViewStyle(PageTabViewStyle(indexDisplayMode:.never))
.animation(Animation.easeInOut(duration: 0.5))
.transition(.slide)
}
}
struct TestView_Previews: PreviewProvider {
static var previews: some View {
T1()
}
}
Can anyone explain the difference between the two?
Thnaks
Upvotes: 0
Views: 294
Reputation: 9665
I think Paul Hudson explains it in this article: Creating tabs with TabView and tabItem() the gist of it is that the tabs are not an array of individual tabs, so to keep track of them you should use a tag()
. Why using the index range works, I am not sure. I suspect it is because you end up with an index that mimics your page index, but that is not the same thing.
If you do use a page, your first one works properly. Of course, you need to use something unique to the array element, so I used it's UUID.
struct T1:View{
@State var T1Array:[T1Object] = [
T1Object(isSelected: true, name: "Albin"),
T1Object(isSelected: false, name: "Albin2"),
T1Object(isSelected: false, name: "Albin3"),
T1Object(isSelected: false, name: "Albin4"),
T1Object(isSelected: false, name: "Albin5"),
T1Object(isSelected: false, name: "Albin6"),
]
@State var pageIndex:UUID = UUID()
init() { // the init() solely is here to set the pageIndex to the first element.
pageIndex = T1Array.first!.id
}
var body: some View {
VStack{
T2(T2Array: $T1Array, pageIndex:$pageIndex)
Text("selected Index:\(pageIndex)")
}
}
}
struct T2:View{
@Binding var T2Array:[T1Object]
@Binding var pageIndex: UUID // make pageIndex a UUID (also in T1)
var body: some View {
TabView(selection: $pageIndex) {
//This doesnt work
ForEach(T2Array) { ele in
Text(ele.name)
.tag(ele.id) // Set the .tag() here
.foregroundColor(ele.isSelected ? Color.blue : Color.black)
.onTapGesture {
print(pageIndex)
pageIndex = T2Array[3].id // This is the 4th element in T2Array
print(pageIndex)
}
}
}.tabViewStyle(PageTabViewStyle(indexDisplayMode:.never))
.animation(Animation.easeInOut(duration: 0.5))
.transition(.slide)
}
}
Upvotes: 1