SwiftUI TabView PageStyle with an optional page

Gerd Castan

In SwiftUI, I want that the state of the first page of a TabView determines if the second page is rendered or does not exist at all.

Complete example code:

import SwiftUI

struct OptionalPageTabView2: View {
    @ObservedObject var model = TabViewModel.shared
    var body: some View {
        TabView {
            let _ = print("rendering TabView")
            Toggle(isOn: $model.on) {
                Text("Show second page")
            }
            //if model.on {
                Page2View()
            //}
            Text("Hello third page")
        }
        .tabViewStyle(.page)
        .indexViewStyle(.page(backgroundDisplayMode: .always))
    }
}

struct Page2View: View {
    @ObservedObject var model = TabViewModel.shared
    var body: some View {
        let _ = print("rendering second page, secondPageState:\(model.on)")
        if model.on {
            Text("Hello second page on")
        } else {
            //Text("Hello second page off")
            EmptyView()
        }
    }
}

class TabViewModel: ObservableObject {
    static let shared = TabViewModel()
    private init(){}
    @Published var on: Bool = true
}

struct OptionalPageTabView_Previews: PreviewProvider {
    static var previews: some View {
        OptionalPageTabView2()
    }
}

Test 1:

  • start example
  • verify console shows something like

rendering TabView rendering second page, secondPageState:true 2021-10-02 11:34:06.700231+0200 TabTest2[4708:100634] [UICollectionViewRecursion] cv == 0x7fb94c01fa00 Disabling recursion trigger logging

  • verify that the index has 3 dots
  • scroll through 3 pages
  • go to the first page again
  • turn off the toggle
  • verify that the console shows something like

rendering TabView rendering second page, secondPageState:false

  • verify that the index has 2 dots

expected: TabView shows 2 pages

problem: TabView shows the original 3 pages

Test 2:

  • start example
  • verify console shows something like

rendering TabView rendering second page, secondPageState:true 2021-10-02 11:34:06.700231+0200 TabTest2[4708:100634] [UICollectionViewRecursion] cv == 0x7fb94c01fa00 Disabling recursion trigger logging

  • verify that the index has 3 dots
  • turn off the toggle
  • verify that the console shows something like

2021-10-02 11:41:45.968083+0200 TabTest2[4838:106887] invalid mode 'kCFRunLoopCommonModes' provided to CFRunLoopRunSpecific - break on _CFRunLoopError_RunCalledWithInvalidMode to debug. This message will only appear once per execution. rendering TabView rendering second page, secondPageState:false

  • scroll
  • verify that the second page is empty
  • go back to the first page
  • turn on the toggle
  • scroll

expected: Second page shows text

problem: Second page is empty

What can I do that the second page is shown or not shown, depending on the state (change) of the first page? What can I do that the second page updates depending on the state change of the fist page?

(Replacing TabView with List shows a list where the second list item is shown depending on the state of the first list item)

Xcode 13, iOS Target 14.0

Raja Kishan

Force refresh tab view by .id

TabView {
    .......
    .......
}.id(model.on)

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related