TabView con "PageTabViewStyle" no actualiza su contenido cuando cambia @State var

Aug 20 2020

Encontré un problema extraño en SwiftUI. Creé una Vista simple que solo contiene un Botón y un TabView que usa PageViewStyle. Parece que el TabView no actualiza su contenido correctamente según el estado de la variable. Parece que el contenido se actualiza de alguna manera, pero la Vista no se actualizará como esperaría

Aquí está el código de mi 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)
    }
}

Así es como se ve el resultado después de tocar la etiqueta varias veces. El estado inicial no es 0 páginas. Después de tocar, esperaría que el contenido de TabView cambie, por lo que todas las páginas serán desplazables y visibles, pero solo el indicador de página actualiza su estado por alguna razón.

Respuestas

7 Asperi Aug 20 2020 at 07:16

TabViewespera tener un contenedor de páginas, pero incluyó solo uno HStack(con contenido dinámico propio), además de encadenar el número de páginas, debe restablecer la vista de pestañas, así que aquí hay una solución.

Probado 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)
            }
        }
    }
}