Gerd Castan
Gerd Castan

Reputation: 6849

SwiftUI TabView PageStyle with an optional page

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:

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

rendering TabView rendering second page, secondPageState:false

expected: TabView shows 2 pages

problem: TabView shows the original 3 pages

Test 2:

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

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

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

Upvotes: 1

Views: 359

Answers (1)

Raja Kishan
Raja Kishan

Reputation: 18914

Force refresh tab view by .id

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

Upvotes: 1

Related Questions