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
CodePudding user response:
Force refresh tab view by .id
TabView {
.......
.......
}.id(model.on)