「PageTabViewStyle」を指定したTabViewは、@ State変数が変更されてもコンテンツを更新しません

Aug 20 2020

SwiftUIで奇妙な問題に遭遇しました。ButtonとPageViewStyleを使用するTabViewのみを保持する単純なビューを作成しました。変数の状態によっては、TabViewがコンテンツを正しく更新しないようです。コンテンツはどういうわけか更新されているようですが、ビューは期待どおりに更新されません

これが私の見解のコードです:

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(独自の動的コンテンツを含む)1つだけを含め、さらにタブビューをリセットする必要があるページ数を連鎖させているため、ここで修正します。

Xcode 12 / iOS14でテスト済み

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