TabView с PageTabViewStyle не обновляет свое содержимое при изменении @State var.

Aug 20 2020

Я столкнулся со странной проблемой в SwiftUI. Я создал простое представление, которое содержит только Button и TabView, использующее PageViewStyle. Кажется, что TabView не обновляет свое содержимое правильно в зависимости от состояния переменной. Кажется, что контент каким-то образом обновляется, но View не будет обновляться так, как я ожидал

Вот код моего взгляда:

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

Вот так выглядит результат после нескольких нажатий на этикетку. Исходное состояние - не 0 страниц. После того, как вы нажмете, я ожидаю, что содержимое TabView изменится, поэтому все страницы будут прокручиваемыми и видимыми, но по какой-то причине только индикатор страницы обновляет его состояние.

Ответы

7 Asperi Aug 20 2020 at 07:16

TabViewпредполагает наличие контейнера страниц, но вы включили только одну HStack(с собственным динамическим содержимым), кроме того, связав количество страниц, вы должны сбросить представление вкладки, так что вот исправление.

Протестировано с 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)
            }
        }
    }
}