I'm experiencing the behaviour outlined below (or see here for a video version). When I navigate programmatically on iPadOS or macOS from a tab that hides the tab bar to another tab, the tab bar remains hidden. The real app has it's entry point in UIKit (i.e. it uses an UITabBarController
instead of a SwiftUI TabView
) but since the problem is reproducible with a SwiftUI only app, I used one for the sake of simplicity.
import SwiftUI
@main
struct HiddenTabBarTestApp: App {
@State private var selectedIndex = 0
var body: some Scene {
WindowGroup {
TabView(selection: $selectedIndex) {
Text("First Tab")
.tabItem {
Label("1", systemImage: "1.circle")
}
.tag(0)
NavigationStack {
Button("Go to first tab") {
selectedIndex = 0
}
.searchable(text: .constant(""))
}
.tabItem {
Label("2", systemImage: "2.circle")
}
.tag(1)
}
}
}
}
Reproduction:
- Create a new SwiftUI App with the iOS App template and use the code from above
- Run the app on iPadOS or macOS
- Navigate to the second tab
- Click into the search bar
- Click the "Go to first tab" button
- The tab bar is no longer visible
I use Xcode 16.2 with iPadOS 18.2 and macOS 15.3.1.
Is this a bug in the Framework or is it the expected behaviour? If it's the expected behaviour, do you have a good solution/workaround that doesn't require me to end the search programmatically (e.g. by using @Environment(\.dismissSearch)
) before navigating to another tab? The goal would be to show the tab bar in the first tab while keeping the search open in the second tab.
Note:
I originally asked this question directly in the Apple Developer Forums but didn't get a response there (see here).
I'm experiencing the behaviour outlined below (or see here for a video version). When I navigate programmatically on iPadOS or macOS from a tab that hides the tab bar to another tab, the tab bar remains hidden. The real app has it's entry point in UIKit (i.e. it uses an UITabBarController
instead of a SwiftUI TabView
) but since the problem is reproducible with a SwiftUI only app, I used one for the sake of simplicity.
import SwiftUI
@main
struct HiddenTabBarTestApp: App {
@State private var selectedIndex = 0
var body: some Scene {
WindowGroup {
TabView(selection: $selectedIndex) {
Text("First Tab")
.tabItem {
Label("1", systemImage: "1.circle")
}
.tag(0)
NavigationStack {
Button("Go to first tab") {
selectedIndex = 0
}
.searchable(text: .constant(""))
}
.tabItem {
Label("2", systemImage: "2.circle")
}
.tag(1)
}
}
}
}
Reproduction:
- Create a new SwiftUI App with the iOS App template and use the code from above
- Run the app on iPadOS or macOS
- Navigate to the second tab
- Click into the search bar
- Click the "Go to first tab" button
- The tab bar is no longer visible
I use Xcode 16.2 with iPadOS 18.2 and macOS 15.3.1.
Is this a bug in the Framework or is it the expected behaviour? If it's the expected behaviour, do you have a good solution/workaround that doesn't require me to end the search programmatically (e.g. by using @Environment(\.dismissSearch)
) before navigating to another tab? The goal would be to show the tab bar in the first tab while keeping the search open in the second tab.
Note:
I originally asked this question directly in the Apple Developer Forums but didn't get a response there (see here).
- Could not replicate the problem on macOS, all works well for me, on macOS Sequoia 15.4 Beta (24E5238a), using Xcode 16.3 beta 3 (16E5129f). Maybe it was a bug that has been fixed. – workingdog support Ukraine Commented Mar 18 at 22:50
- Can replicate the problem on iPadOS 18.3.2. – workingdog support Ukraine Commented Mar 19 at 0:35
- Thanks for the information! Good to know. – finebel Commented Mar 19 at 18:26
1 Answer
Reset to default 1It is probably a bug in the iPadOS, try this workaround, works for me, tested on iPadOS 18.3.2.
Add .id(selectedIndex)
to your TabView
.
TabView(selection: $selectedIndex) {
....
}
.id(selectedIndex) // <--- here
EDIT-1:
From your comment, ...the TabView is rebuild completely from scratch with every tab change...
, the View/body is diff (very efficient),
and this can occur many times and at
any time SwiftUI sees fit, with or without the id
.
The search does not end once you change the tab. Here is my test code that shows this:
Example test code:
@main
struct HiddenTabBarTestApp: App {
@State private var selectedIndex = 0
@State private var searcher = "" // <--- here
var body: some Scene {
WindowGroup {
Text(searcher) // <--- for testing
TabView(selection: $selectedIndex) {
Text("First Tab")
.tabItem {
Label("1", systemImage: "1.circle")
}
.tag(0)
NavigationStack {
Button("Go to first tab") {
selectedIndex = 0
}
.searchable(text: $searcher) // <--- here
}
.tabItem {
Label("2", systemImage: "2.circle")
}
.tag(1)
}
.id(selectedIndex) // <--- here
}
}
}