Hi the bug is well known. Generally it helps when you put the tabview into inactive scrollview with certain frame modifier, like this:
struct ContentView: View {
var body: some View {
ScrollView([])
TabView{
TabItemView(color: .red, title: "Page 1")
TabItemView(color: .yellow, title: "Page 2")
TabItemView(color: .green, title: "Page 3")
TabItemView(color: .blue, title: "Page 4")
}
.tabViewStyle(.page)
.background(Color.indigo)
}
}
.frame(width: UIScreen.main.bounds.width)
}
This should fix the views in the middle in case of rotations. However, it might happen that when you use some array and iterate over it using ForEach inside the TabView, the elements are arbitrarily changed by TabView while rotating view. In that case it helps to keep tracking the current and previous orientation using states and build some logic onChange to prevent TabView to doing that. Like some wrapper adding layer between the binded state. Like:
struct TabView: View {
@State var pages: Int = 1
var array: [Int] = [1,2,3,4,5]
var body: some View {
VStack {
TabViewContent(selection: $pages, usage: .one) {
ForEach(array, id: \.self) { index in
Text("This is: \(pages) \(index)")
.tag(index)
}
}
}
}
}
Wrapper with logic:
struct TabViewContent<Selection: Hashable, Content: View>: View {
@Binding var selection: Selection
@State var selectionInternal: Selection
@State var previousOrientation: UIDeviceOrientation = .unknown
@State var currentOrientation: UIDeviceOrientation = .unknown
@ViewBuilder var content: () -> Content
internal init(selection: Binding<Selection>, content: @escaping () -> Content) {
self.content = content
_selection = selection
_selectionInternal = State(initialValue: selection.wrappedValue)
}
var body: some View {
TabView(selection: $selection, content: content)
.tabViewStyle(.page)
.onChange(of: UIDevice.current.orientation) { newOrientation in
currentOrientation = newOrientation
}
.onChange(of: selectionInternal) { value in
if currentOrientation == previousOrientation {
selection = selectionInternal
}
previousOrientation = currentOrientation
}
}
}