Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TabView with "PageTabViewStyle" does not update it's content when @State var changes

I came across a weird Issue in SwiftUI. I created a simple View that only holds a Button and a TabView that uses the PageViewStyle. It seems that the TabView does not update it's content correctly depending on the State of the Variable. It seems that the content gets updated somehow but the View wont be updated how I would expect

Here is the Code of my 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)
    }
}

This is how the result looks after tapping the label several Times. The Initial State is no 0 Pages. After you tap i would expect that the content of the TabView changes so all Pages will be scrollable and visible but just the page indicator updates it State for some reason.

enter image description here

like image 533
Sebastian Boldt Avatar asked Aug 20 '20 06:08

Sebastian Boldt


People also ask

What is pagetabviewstyle for tabview?

In the recent WWDC 2020, Apple introduced an additional style for TabView called PageTabViewStyle. This is equivalent to Horizontal Paging Scroll which is commonly used for the onboarding screen. A TabViewStyle that implements a paged scrolling TabView.

How to enable horizontal page scroll in tabview?

Add .tabViewStyle (PageTabViewStyle ()) at the end of TabView. Your tab should be able to scroll horizontally now. A Horizontal Page Scrolling is not complete without the page indicator.

What is tabview in Salesforce?

It allows us to add the tab view and control the currently selected tab programmatically. The hidden feature of the TabView is that we can use it to show the multiple tabs with page indicators, and those can be controlled by scrolling between them.

How to create scrolling pages with the tabview in SwiftUI?

To create scrolling pages with the TabView in SwiftUI, we need to call the view modifier tabViewStyle and pass an instance of PageTabViewStyle style. If we want to hide the page indicator, we specify the indexDisplayMode parameter for the PageTabViewStyle instance and set it to .never.


1 Answers

TabView expects to have container of pages, but you included only one HStack (with own dynamic content), moreover chaining number of pages you have to reset tab view, so here is a fix.

Tested with Xcode 12 / iOS 14

demo

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)          // << here !!
            }
        }
    }
}

backup

like image 170
Asperi Avatar answered Nov 18 '22 03:11

Asperi