0

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

1 Answer 1

1

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)
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.