Skip to content

fix(ios): keep tab identity when toggling tabBarHidden - #604

Merged
thiagobrez merged 2 commits into
callstack:mainfrom
teddyxfire1992:fix/hide-tab-bar-identity
Oct 22, 2026
Merged

thiagobrez merged 2 commits into
callstack:mainfrom
teddyxfire1992:fix/hide-tab-bar-identity

Conversation

@teddyxfire1992

@teddyxfire1992 teddyxfire1992 commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

PR Description

Closes #593.

The fix was proposed by @pawarren in the issue; this PR applies it and adds a changeset.

hideTabBar is a @ViewBuilder that branched on flag, so toggling tabBarHidden swapped the _ConditionalContent case and changed the view's structural identity. SwiftUI then rebuilt the tab content, which dismissed sheets presented from inside the tab and dropped text input focus. A common trigger is hiding the tab bar while the keyboard is up: focusing a field raises the keyboard, the app hides the tab bar, and the field loses focus and the sheet is dismissed.

This branches only on #available, which is constant at runtime, and passes the flag as the value: .toolbar(flag ? .hidden : .automatic, for: .tabBar). .automatic is the default visibility, so the visible tab bar behaves as before. The pre-iOS 16 fallback is unchanged.

On iOS 18+ (NewTabView) the modifier wraps each tab's content. On older iOS (LegacyTabView) it wraps the whole TabView, so the fix covers both.

How to test?

  1. Create an app with react-native-bottom-tabs and @expo/ui. In a tab, render a BottomSheet containing a TextField.
  2. Hide the tab bar while the keyboard is up:
    useEffect(() => {
      const show = Keyboard.addListener('keyboardWillShow', () => setTabBarHidden(true))
      const hide = Keyboard.addListener('keyboardWillHide', () => setTabBarHidden(false))
      return () => {
        show.remove()
        hide.remove()
      }
    }, [])
  3. Open the sheet and tap the text field.
  4. Before: the keyboard closes at once, typing does nothing, and the sheet's onDismiss fires (2–3 times) before it is presented again.
  5. After: the field keeps focus, typing works, onDismiss does not fire, and the tab bar hides while the keyboard is up.

The same issue shows without a sheet: a plain TextInput in a tab loses focus as soon as the keyboard hides the tab bar.

Verified with agent-device in a fresh Expo SDK 57 app (React Native 0.86.3, @expo/ui 57.0.26, react-native-bottom-tabs 1.5.0 patched in place), plus the example app's Tab Bar Hidden screen with a TextInput.

Recordings

iOS 26 before

before-ios26.mov

iOS 26 after

after-ios26.mov

iOS 17 before

before-ios17.mov

iOS 17 after

after-ios17.mov

hideTabBar branched on the flag inside a @ViewBuilder, so toggling
tabBarHidden swapped _ConditionalContent cases and changed the view's
structural identity. SwiftUI rebuilt the tab content, which dismissed
sheets presented from the tab and dropped text input focus. Branch on
availability only and pass the flag as the toolbar visibility value.

Fixes callstack#593
Comment thread packages/react-native-bottom-tabs/ios/TabViewImpl.swift Outdated
@thiagobrez
thiagobrez added this pull request to the merge queue Oct 22, 2026
Merged via the queue into callstack:main with commit 89089e3 Oct 22, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Toggling tabBarHidden destroys the tab's SwiftUI identity, dismissing presented sheets

2 participants