TabView con "PageTabViewStyle" non aggiorna il contenuto quando cambia @State var

Aug 20 2020

Mi sono imbattuto in uno strano problema in SwiftUI. Ho creato una semplice visualizzazione che contiene solo un pulsante e una visualizzazione a schede che utilizza PageViewStyle. Sembra che il TabView non aggiorni il contenuto correttamente a seconda dello stato della variabile. Sembra che il contenuto venga aggiornato in qualche modo, ma la vista non verrà aggiornata come mi aspetterei

Ecco il codice della mia vista:

struct ContentView: View {
    @State var numberOfPages: Int = 0
    @State var selectedIndex = 0
    
    var body: some View {
        VStack {
            Text("Tap Me").onTapGesture(count: 1, perform: {
                self.numberOfPages = [2,5,10,15].randomElement()!
                self.selectedIndex = 0
            })
            
            TabView(selection: $selectedIndex){
                ForEach(0..<numberOfPages, id: \.self) { index in
                    Text("\(index)").background(Color.red)
                }
            }
            .frame(height: 300)
            .tabViewStyle(PageTabViewStyle(indexDisplayMode: .automatic))
        }.background(Color.blue)
    }
}

Ecco come appare il risultato dopo aver toccato più volte l'etichetta. Lo stato iniziale non è 0 pagine. Dopo aver toccato, mi aspetto che il contenuto di TabView cambi in modo che tutte le pagine siano scorrevoli e visibili, ma solo l'indicatore di pagina lo aggiorna per qualche motivo.

Risposte

7 Asperi Aug 20 2020 at 07:16

TabViewprevede di avere un contenitore di pagine, ma ne hai incluso solo uno HStack(con il proprio contenuto dinamico), inoltre concatenando il numero di pagine devi reimpostare la visualizzazione a schede, quindi ecco una soluzione.

Testato con Xcode 12 / iOS 14

struct ContentView: View {
    @State var numberOfPages: Int = 0

    var body: some View {
        VStack {
            Text("Tap Me").onTapGesture(count: 1, perform: {
                self.numberOfPages = [2,5,10,15].randomElement()!
            })
            if self.numberOfPages != 0 {
                TabView {
                    ForEach(0..<numberOfPages, id: \.self) { index in
                        Text("\(index)").frame(width: 300).background(Color.red)
                    }
                }
                .tabViewStyle(PageTabViewStyle(indexDisplayMode: .automatic))
                .frame(height: 300)
                .id(numberOfPages)
            }
        }
    }
}