Why tabView jumps one view back on orientation change?

I have a simple tabView, and when I change the orientation of my iPhone (from portrait to landscape) tab jumps one tab back. For example, if you are on page 2 and rotate your device, it goes to 1, but it should stay on page 2. Why this unwanted jump happens? Am I missing something?

(The weird thing about this issue is when you turn the device back to portrait (from landscape), it doesn't jump.)

Code Block
struct ContentView: View {
    @State var currentPage: Int = 1
    var body: some View {
            ZStack {
                TabView(selection: $currentPage) {
                    Text("1").tag(0)
                    Text("2").tag(1)
                    Text("3").tag(2)
                }
.indexViewStyle(PageIndexViewStyle(backgroundDisplayMode: .never))
.tabViewStyle(PageTabViewStyle())
        }
    }
}

I'm running the latest iOS and Xcode version.
I have the same issue. Did you find a solution?
Same here - in my case it is even more than one Tab jump that the rotation to landscape or back to portrait causes.

Coud it be because the TabView-frame is much wider than tall ? But shouldn't the TabView rotation take care of this.

My rotation is made as follows:

Code Block Swift
struct DeviceRotationViewModifier: ViewModifier {
   
  let action: (UIDeviceOrientation) -> Void
  func body(content: Content) -> some View {
    content
      .onAppear()
      .onReceive(NotificationCenter.default.publisher(for: UIDevice.orientationDidChangeNotification)) { _ in
        action(UIDevice.current.orientation)
      }
  }
}

Code Block Swift
extension View {
   
  func onRotate(perform action: @escaping (UIDeviceOrientation) -> Void) -> some View {
    self.modifier(DeviceRotationViewModifier(action: action))
  }
}


And finally, where I rotate my TabView:

Code Block Swift
TabView(selection: self.$selectedTab) {
...
}
  .tabViewStyle(PageTabViewStyle())
    .onRotate { _ in
      print(selectedTab)
    }


Any solution to this problem is highly appreciated, thank you.

If you set the frame width on the tabview, the page will not change on rotation. I use the maximum of the screen width and height as the tabview frame width, and that seems to work well.

struct ContentView: View {

    @State var currentPage: Int = 1

    var body: some View {

            ZStack {

                TabView(selection: $currentPage) {

                    Text("1").tag(0)

                    Text("2").tag(1)

                    Text("3").tag(2)

                }
.frame(width: max(UIScreen.main.bounds.width, UIScreen.main.bounds.height))      .indexViewStyle(PageIndexViewStyle(backgroundDisplayMode: .never))
.tabViewStyle(PageTabViewStyle())

        }

    }

}

 

The above frame(width:) work-around did not work for me (iOS 16 beta 3). I was getting jerky animations and sometimes incorrect sizes. What did work was to set the selectedTab back to the proper tab, as follows:

.onReceive(NotificationCenter.default.publisher(for: UIDevice.orientationDidChangeNotification)) { info in
    let currentTab = selectedTab
    DispatchQueue.main.async {
       if currentTab != selectedTab {
          selectedTab = currentTab
       }
     }
 }

In the code above, selectedTab is my @State variable that is bound to the TabView's selection.

The value of selectedTab when the onReceive is executed is the current value -- the value before this bug changes the selection. Dispatching and setting selectedTab back corrects the change from the bug.

This seems to work well for me.

Filed as FB10871235.

Any solution for this please ?

Why tabView jumps one view back on orientation change?
 
 
Q