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

Я столкнулся со странной проблемой в 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 изменится, поэтому все страницы будут прокручиваемыми и видимыми, но по какой-то причине только индикатор страницы обновляет его состояние.

введите описание изображения здесь


person Sebastian Boldt    schedule 20.08.2020    source источник


Ответы (1)


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)
            }
        }
    }
}
person Asperi    schedule 20.08.2020