From 5bc4090cba3c31be4e109ad052d831adbacc4a03 Mon Sep 17 00:00:00 2001 From: alex Date: Sun, 14 Dec 2025 16:07:13 +1100 Subject: [PATCH 1/2] feat(ios): add searchable support for tabs --- apps/example/ios/Podfile.lock | 8 +-- apps/example/src/Examples/FourTabs.tsx | 21 +++++--- .../NativeBottomTabsEmbeddedStacks.tsx | 27 +++++++--- .../ios/RCTTabViewComponentView.mm | 25 ++++++++- .../ios/RepresentableViewController.swift | 43 +++++++++++++++ .../ios/TabView/NewTabView.swift | 36 ++++++++++--- .../ios/TabViewImpl.swift | 8 ++- .../ios/TabViewProps.swift | 18 +++++++ .../ios/TabViewProvider.swift | 18 +++++-- .../react-native-bottom-tabs/src/TabView.tsx | 53 +++++++++++++++++++ .../src/TabViewNativeComponent.ts | 12 +++++ .../react-native-bottom-tabs/src/types.ts | 2 + .../createNativeBottomTabNavigator.tsx | 4 ++ packages/react-navigation/src/types.ts | 8 +++ .../src/views/NativeBottomTabView.tsx | 4 ++ 15 files changed, 256 insertions(+), 31 deletions(-) create mode 100644 packages/react-native-bottom-tabs/ios/RepresentableViewController.swift diff --git a/apps/example/ios/Podfile.lock b/apps/example/ios/Podfile.lock index 66760fdf..52cb2ba0 100644 --- a/apps/example/ios/Podfile.lock +++ b/apps/example/ios/Podfile.lock @@ -1748,7 +1748,7 @@ PODS: - React-RCTFBReactNativeSpec - ReactCommon/turbomodule/core - SocketRocket - - react-native-bottom-tabs (1.0.5): + - react-native-bottom-tabs (1.1.0): - boost - DoubleConversion - fast_float @@ -1766,7 +1766,7 @@ PODS: - React-graphics - React-ImageManager - React-jsi - - react-native-bottom-tabs/common (= 1.0.5) + - react-native-bottom-tabs/common (= 1.1.0) - React-NativeModulesApple - React-RCTFabric - React-renderercss @@ -1778,7 +1778,7 @@ PODS: - SocketRocket - SwiftUIIntrospect (~> 1.0) - Yoga - - react-native-bottom-tabs/common (1.0.5): + - react-native-bottom-tabs/common (1.1.0): - boost - DoubleConversion - fast_float @@ -2842,7 +2842,7 @@ SPEC CHECKSUMS: React-logger: a3cb5b29c32b8e447b5a96919340e89334062b48 React-Mapbuffer: 9d2434a42701d6144ca18f0ca1c4507808ca7696 React-microtasksnativemodule: 75b6604b667d297292345302cc5bfb6b6aeccc1b - react-native-bottom-tabs: 8e918142554e3878f043b23bdf93049b34a78ca6 + react-native-bottom-tabs: e33312fc663d163f0be73d3474dfb448ba38dad8 react-native-safe-area-context: c6e2edd1c1da07bdce287fa9d9e60c5f7b514616 React-NativeModulesApple: 879fbdc5dcff7136abceb7880fe8a2022a1bd7c3 React-oscompat: 93b5535ea7f7dff46aaee4f78309a70979bdde9d diff --git a/apps/example/src/Examples/FourTabs.tsx b/apps/example/src/Examples/FourTabs.tsx index 4c32ece6..fde4aebc 100644 --- a/apps/example/src/Examples/FourTabs.tsx +++ b/apps/example/src/Examples/FourTabs.tsx @@ -4,7 +4,7 @@ import { Article } from '../Screens/Article'; import { Albums } from '../Screens/Albums'; import { Contacts } from '../Screens/Contacts'; import { Chat } from '../Screens/Chat'; -import type { ColorValue } from 'react-native'; +import { Platform, type ColorValue } from 'react-native'; interface Props { disablePageAnimations?: boolean; @@ -48,22 +48,31 @@ export default function FourTabs({ badge: '5', hidden: hideOneTab, }, + + { + key: 'chat', + focusedIcon: require('../../assets/icons/chat_dark.png'), + title: 'Chat', + }, { key: 'contacts', focusedIcon: require('../../assets/icons/person_dark.png'), title: 'Contacts', badge: ' ', - }, - { - key: 'chat', - focusedIcon: require('../../assets/icons/chat_dark.png'), - title: 'Chat', + role: 'search', + searchable: true, + navigationBarToolbarStyle: + Platform.Version === 26 || Platform.Version === '26.0' + ? 'hidden' + : 'visible', }, ]); return ( console.log('isFocused', isFocused)} sidebarAdaptable + onSearchTextChange={(text) => console.log(text)} disablePageAnimations={disablePageAnimations} scrollEdgeAppearance={scrollEdgeAppearance} navigationState={{ index, routes }} diff --git a/apps/example/src/Examples/NativeBottomTabsEmbeddedStacks.tsx b/apps/example/src/Examples/NativeBottomTabsEmbeddedStacks.tsx index 63fe64aa..112ff11e 100644 --- a/apps/example/src/Examples/NativeBottomTabsEmbeddedStacks.tsx +++ b/apps/example/src/Examples/NativeBottomTabsEmbeddedStacks.tsx @@ -4,6 +4,7 @@ import { Contacts } from '../Screens/Contacts'; import { Chat } from '../Screens/Chat'; import { createNativeBottomTabNavigator } from '@bottom-tabs/react-navigation'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; +import { Platform } from 'react-native'; const headerOptions = { headerShown: true, @@ -67,7 +68,10 @@ function ChatStackScreen() { function NativeBottomTabsEmbeddedStacks() { return ( - + console.log(text)} + onSearchFocusChange={(isFocused) => console.log('isFocused', isFocused)} + > require('../../assets/icons/grid_dark.png'), }} /> - require('../../assets/icons/person_dark.png'), - }} - /> + + require('../../assets/icons/person_dark.png'), + searchable: true, + navigationBarToolbarStyle: + Platform.Version === 26 || Platform.Version === '26.0' + ? 'hidden' + : 'visible', + }} + /> ); } diff --git a/packages/react-native-bottom-tabs/ios/RCTTabViewComponentView.mm b/packages/react-native-bottom-tabs/ios/RCTTabViewComponentView.mm index c41f9316..281a823a 100644 --- a/packages/react-native-bottom-tabs/ios/RCTTabViewComponentView.mm +++ b/packages/react-native-bottom-tabs/ios/RCTTabViewComponentView.mm @@ -192,7 +192,9 @@ - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const & hidden:item.hidden testID:RCTNSStringFromStringNilIfEmpty(item.testID) role:RCTNSStringFromStringNilIfEmpty(item.role) - preventsDefault:item.preventsDefault + preventsDefault:item.preventsDefault + searchable:item.searchable + navigationBarToolbarStyle:RCTNSStringFromStringNilIfEmpty(item.navigationBarToolbarStyle) ]; [result addObject:tabInfo]; @@ -210,7 +212,8 @@ - (void)updateState:(const facebook::react::State::Shared &)state oldState:(cons } } -// MARK: TabViewProviderDelegate + + // MARK: TabViewProviderDelegate - (void)onPageSelectedWithKey:(NSString *)key reactTag:(NSNumber *)reactTag { auto eventEmitter = std::static_pointer_cast(_eventEmitter); @@ -221,6 +224,24 @@ - (void)onPageSelectedWithKey:(NSString *)key reactTag:(NSNumber *)reactTag { } } +- (void)onSearchFocusChangeWithIsFocused:(BOOL)isFocused reactTag:(NSNumber *)reactTag{ + auto eventEmitter = std::static_pointer_cast(_eventEmitter); + if (eventEmitter) { + eventEmitter->onSearchFocusChange(RNCTabViewEventEmitter::OnSearchFocusChange{ + .isFocused = isFocused + }); + } +} +- (void)onSearchTextChangeWithText:(NSString * _Nonnull)text reactTag:(NSNumber * _Nullable)reactTag { + auto eventEmitter = std::static_pointer_cast(_eventEmitter); + if (eventEmitter) { + eventEmitter->onSearchTextChange(RNCTabViewEventEmitter::OnSearchTextChange{ + .text = [text cStringUsingEncoding:NSUTF8StringEncoding] + }); + } +} + + - (void)onLongPressWithKey:(NSString *)key reactTag:(NSNumber *)reactTag { auto eventEmitter = std::static_pointer_cast(_eventEmitter); if (eventEmitter) { diff --git a/packages/react-native-bottom-tabs/ios/RepresentableViewController.swift b/packages/react-native-bottom-tabs/ios/RepresentableViewController.swift new file mode 100644 index 00000000..bd5d6fa2 --- /dev/null +++ b/packages/react-native-bottom-tabs/ios/RepresentableViewController.swift @@ -0,0 +1,43 @@ +import Foundation +import SwiftUI + +/** + Helper used to render UIViewController inside of SwiftUI. + This solves issues in some cases that can't found root UINavigationController. + */ +struct RepresentableViewController: UIViewControllerRepresentable { + func updateUIViewController(_ uiViewController: UIViewController, context: Context) { + + } + + + var view: PlatformView + +#if os(macOS) + + func makeNSView(context: Context) -> PlatformView { + let wrapper = NSView() + wrapper.addSubview(view) + return wrapper + } + + func updateNSView(_ nsView: PlatformView, context: Context) {} + +#else + + func makeUIView(context: Context) -> PlatformView { + let wrapper = UIView() + wrapper.addSubview(view) + return wrapper + } + func makeUIViewController(context: Context) -> UIViewController { + let contentVC = UIViewController() + contentVC.view.backgroundColor = .clear + contentVC.view.addSubview(view) + + return contentVC + } + func updateUIView(_ uiView: PlatformView, context: Context) {} + +#endif +} diff --git a/packages/react-native-bottom-tabs/ios/TabView/NewTabView.swift b/packages/react-native-bottom-tabs/ios/TabView/NewTabView.swift index d6993158..d7901482 100644 --- a/packages/react-native-bottom-tabs/ios/TabView/NewTabView.swift +++ b/packages/react-native-bottom-tabs/ios/TabView/NewTabView.swift @@ -2,12 +2,15 @@ import React import SwiftUI @available(iOS 18, macOS 15, visionOS 2, tvOS 18, *) -struct NewTabView: AnyTabView { +struct NewTabView: AnyTabView { @ObservedObject var props: TabViewProps - var onLayout: (CGSize) -> Void var onSelect: (String) -> Void + var onSearchTextChange: ((String) -> Void) + var onSearchFocusChange: ((Bool) -> Void) var updateTabBarAppearance: () -> Void + @FocusState var focused: Bool + @State var query = "" @ViewBuilder var body: some View { @@ -29,10 +32,31 @@ struct NewTabView: AnyTabView { ) Tab(value: tabData.key, role: tabData.role?.convert()) { - RepresentableView(view: child.view) - .ignoresSafeArea(.container, edges: .all) - .tabAppear(using: context) - .hideTabBar(props.tabBarHidden) + //Have to wrap in NavigationView to use searchable + if(tabData.searchable){ + NavigationView{ + //If it is not wrapped in UIViewController, it will crash. + RepresentableViewController(view: child.view) + .ignoresSafeArea(.container, edges: .all) + .tabAppear(using: context) + .hideTabBar(props.tabBarHidden) + .toolbar(tabData.navigationBarToolbarStyle.convert(), for: .navigationBar) + .searchable(text: $query) + .searchFocused($focused) + .onChange(of: focused){ newValue in + onSearchFocusChange(newValue) + } + .onChange(of: query) { newValue in + onSearchTextChange(newValue) + } + } + }else{ + RepresentableView(view: child.view) + .ignoresSafeArea(.container, edges: .all) + .tabAppear(using: context) + .hideTabBar(props.tabBarHidden) + } + } label: { TabItem( title: tabData.title, diff --git a/packages/react-native-bottom-tabs/ios/TabViewImpl.swift b/packages/react-native-bottom-tabs/ios/TabViewImpl.swift index 72938be9..bb0985da 100644 --- a/packages/react-native-bottom-tabs/ios/TabViewImpl.swift +++ b/packages/react-native-bottom-tabs/ios/TabViewImpl.swift @@ -18,7 +18,9 @@ struct TabViewImpl: View { NewTabView( props: props, onLayout: onLayout, - onSelect: onSelect + onSelect: onSelect, + onSearchTextChange: onSearchTextChange, + onSearchFocusChange: onSearchFocusChange, ) { #if !os(macOS) updateTabBarAppearance(props: props, tabBar: tabBar) @@ -36,11 +38,13 @@ struct TabViewImpl: View { } } } - + var onSelect: (_ key: String) -> Void var onLongPress: (_ key: String) -> Void var onLayout: (_ size: CGSize) -> Void var onTabBarMeasured: (_ height: Int) -> Void + var onSearchTextChange: (_ text: String) -> Void + var onSearchFocusChange: (_ focused: Bool) -> Void var body: some View { tabContent diff --git a/packages/react-native-bottom-tabs/ios/TabViewProps.swift b/packages/react-native-bottom-tabs/ios/TabViewProps.swift index cd098c07..8e7b095a 100644 --- a/packages/react-native-bottom-tabs/ios/TabViewProps.swift +++ b/packages/react-native-bottom-tabs/ios/TabViewProps.swift @@ -39,6 +39,24 @@ public enum TabBarRole: String { } } +public enum ToolbarStyle: String { + case automatic + case hidden + case visible + + @available(iOS 18, macOS 15, visionOS 2, tvOS 18, *) + func convert() -> Visibility { + switch self { + case .automatic: + return .automatic + case .hidden: + return .hidden + case .visible: + return .visible + } + } +} + struct IdentifiablePlatformView: Identifiable, Equatable { let id = UUID() let view: PlatformView diff --git a/packages/react-native-bottom-tabs/ios/TabViewProvider.swift b/packages/react-native-bottom-tabs/ios/TabViewProvider.swift index 013032f0..99ab10f6 100644 --- a/packages/react-native-bottom-tabs/ios/TabViewProvider.swift +++ b/packages/react-native-bottom-tabs/ios/TabViewProvider.swift @@ -13,7 +13,8 @@ public final class TabInfo: NSObject { public let testID: String? public let role: TabBarRole? public let preventsDefault: Bool - + public let searchable: Bool + public let navigationBarToolbarStyle: ToolbarStyle public init( key: String, title: String, @@ -23,7 +24,9 @@ public final class TabInfo: NSObject { hidden: Bool, testID: String?, role: String?, - preventsDefault: Bool = false + preventsDefault: Bool = false, + searchable:Bool = false, + navigationBarToolbarStyle: String? = "automatic" ) { self.key = key self.title = title @@ -34,6 +37,8 @@ public final class TabInfo: NSObject { self.testID = testID self.role = TabBarRole(rawValue: role ?? "") self.preventsDefault = preventsDefault + self.searchable = searchable + self.navigationBarToolbarStyle = ToolbarStyle(rawValue: navigationBarToolbarStyle ?? "automatic") ?? .automatic super.init() } } @@ -43,6 +48,8 @@ public final class TabInfo: NSObject { func onLongPress(key: String, reactTag: NSNumber?) func onTabBarMeasured(height: Int, reactTag: NSNumber?) func onLayout(size: CGSize, reactTag: NSNumber?) + func onSearchTextChange(text: String, reactTag: NSNumber?) + func onSearchFocusChange(isFocused: Bool, reactTag: NSNumber?) } @objc public class TabViewProvider: PlatformView { @@ -58,6 +65,8 @@ public final class TabInfo: NSObject { @objc var onTabLongPress: RCTDirectEventBlock? @objc var onTabBarMeasured: RCTDirectEventBlock? @objc var onNativeLayout: RCTDirectEventBlock? + @objc var onSearchTextChange : RCTDirectEventBlock? + @objc var onSearchFocusChange : RCTDirectEventBlock? @objc public var icons: NSArray? { didSet { @@ -191,7 +200,6 @@ public final class TabInfo: NSObject { if self.hostingController != nil { return } - self.hostingController = PlatformHostingController(rootView: TabViewImpl(props: props) { key in self.delegate?.onPageSelected(key: key, reactTag: self.reactTag) } onLongPress: { key in @@ -200,6 +208,10 @@ public final class TabInfo: NSObject { self.delegate?.onLayout(size: size, reactTag: self.reactTag) } onTabBarMeasured: { height in self.delegate?.onTabBarMeasured(height: height, reactTag: self.reactTag) + } onSearchTextChange : { text in + self.delegate?.onSearchTextChange(text: text, reactTag: self.reactTag) + } onSearchFocusChange: { isFocused in + self.delegate?.onSearchFocusChange(isFocused: isFocused, reactTag: self.rootTag) }) if let hostingController = self.hostingController, let parentViewController = reactViewController() { diff --git a/packages/react-native-bottom-tabs/src/TabView.tsx b/packages/react-native-bottom-tabs/src/TabView.tsx index 41b9cb37..33a43d70 100644 --- a/packages/react-native-bottom-tabs/src/TabView.tsx +++ b/packages/react-native-bottom-tabs/src/TabView.tsx @@ -1,7 +1,9 @@ import React, { useLayoutEffect, useRef } from 'react'; import type { + OnChangeTextEventDataData, OnNativeLayout, OnPageSelectedEventData, + OnSearchBarFocusChangeData, OnTabBarMeasured, TabViewItems, } from './TabViewNativeComponent'; @@ -91,10 +93,25 @@ interface Props { * Callback which is called on tab change, receives the index of the new tab as argument. */ onIndexChange: (index: number) => void; + /** + * Callback which is called on search text change, receives the text as argument. Only works if `searchable` is `true`. + */ + onSearchTextChange?: (text: string) => void; + /** + * Callback which is called on search focus change, receives the isFocused as argument. Only works if `searchable` is `true`. + */ + onSearchFocusChange?: (isFocused: boolean) => void; /** * Callback which is called on long press on tab, receives the index of the tab as argument. */ onTabLongPress?: (index: number) => void; + + /** + * Get navigation bar toolbar style for the tab, uses `route.navigationBarToolbarStyle` by default. + */ + getNavigationBarToolbarStyle?: (props: { + route: Route; + }) => 'automatic' | 'hidden' | 'visible' | undefined; /** * Get lazy for the current screen. Uses true by default. */ @@ -115,6 +132,14 @@ interface Props { * Get badge text color for the tab, uses `route.badgeTextColor` by default. (Android only) */ getBadgeTextColor?: (props: { route: Route }) => ColorValue | undefined; + /** + * Get searchable for the tab, uses `route.searchable` by default. + */ + getSearchable?: (props: { route: Route }) => boolean | undefined; + /** + * Get navigation bar toolbar style for the tab, uses `route.navigationBarToolbarStyle` by default. + */ + /** * Get active tint color for the tab, uses `route.activeTintColor` by default. */ @@ -229,6 +254,9 @@ const TabView = ({ getActiveTintColor = ({ route }: { route: Route }) => route.activeTintColor, getTestID = ({ route }: { route: Route }) => route.testID, getRole = ({ route }: { route: Route }) => route.role, + getNavigationBarToolbarStyle = ({ route }: { route: Route }) => + route.navigationBarToolbarStyle, + getSearchable = ({ route }: { route: Route }) => route.searchable, getSceneStyle = ({ route }: { route: Route }) => route.style, getPreventsDefault = ({ route }: { route: Route }) => route.preventsDefault, hapticFeedbackEnabled = false, @@ -239,6 +267,8 @@ const TabView = ({ tabBarStyle, tabLabelStyle, renderBottomAccessoryView, + onSearchTextChange, + onSearchFocusChange, ...props }: Props) => { // @ts-ignore @@ -308,10 +338,14 @@ const TabView = ({ hidden: getHidden?.({ route }), testID: getTestID?.({ route }), role: getRole?.({ route }), + searchable: getSearchable?.({ route }), preventsDefault: getPreventsDefault?.({ route }), + navigationBarToolbarStyle: getNavigationBarToolbarStyle?.({ route }), }; }), [ + getSearchable, + getNavigationBarToolbarStyle, trimmedRoutes, icons, getLabelText, @@ -352,6 +386,23 @@ const TabView = ({ [trimmedRoutes, onTabLongPress] ); + const handleSearchTextChange = React.useCallback( + ({ nativeEvent: { text } }: { nativeEvent: OnChangeTextEventDataData }) => { + onSearchTextChange?.(text); + }, + [onSearchTextChange] + ); + + const handleSearchFocusChange = React.useCallback( + ({ + nativeEvent: { isFocused }, + }: { + nativeEvent: OnSearchBarFocusChangeData; + }) => { + onSearchFocusChange?.(isFocused); + }, + [onSearchFocusChange] + ); const handlePageSelected = React.useCallback( ({ nativeEvent: { key } }: { nativeEvent: OnPageSelectedEventData }) => { jumpTo(key); @@ -397,6 +448,8 @@ const TabView = ({ onPageSelected={handlePageSelected} onTabBarMeasured={handleTabBarMeasured} onNativeLayout={handleNativeLayout} + onSearchFocusChange={handleSearchFocusChange} + onSearchTextChange={handleSearchTextChange} hapticFeedbackEnabled={hapticFeedbackEnabled} activeTintColor={activeTintColor} inactiveTintColor={inactiveTintColor} diff --git a/packages/react-native-bottom-tabs/src/TabViewNativeComponent.ts b/packages/react-native-bottom-tabs/src/TabViewNativeComponent.ts index 7949e156..2f4feab7 100644 --- a/packages/react-native-bottom-tabs/src/TabViewNativeComponent.ts +++ b/packages/react-native-bottom-tabs/src/TabViewNativeComponent.ts @@ -33,13 +33,25 @@ export type TabViewItems = ReadonlyArray<{ hidden?: boolean; testID?: string; role?: string; + searchable?: boolean; preventsDefault?: boolean; + navigationBarToolbarStyle?: string; +}>; + +export type OnChangeTextEventDataData = Readonly<{ + text: string; +}>; + +export type OnSearchBarFocusChangeData = Readonly<{ + isFocused: boolean; }>; export interface TabViewProps extends ViewProps { items: TabViewItems; selectedPage: string; onPageSelected?: DirectEventHandler; + onSearchTextChange?: DirectEventHandler; + onSearchFocusChange?: DirectEventHandler; onTabLongPress?: DirectEventHandler; onTabBarMeasured?: DirectEventHandler; onNativeLayout?: DirectEventHandler; diff --git a/packages/react-native-bottom-tabs/src/types.ts b/packages/react-native-bottom-tabs/src/types.ts index 612dcd4f..5e7f5f7a 100644 --- a/packages/react-native-bottom-tabs/src/types.ts +++ b/packages/react-native-bottom-tabs/src/types.ts @@ -23,6 +23,8 @@ export type BaseRoute = { freezeOnBlur?: boolean; style?: StyleProp; preventsDefault?: boolean; + searchable?: boolean; + navigationBarToolbarStyle?: 'automatic' | 'hidden' | 'visible'; }; export type NavigationState = { diff --git a/packages/react-navigation/src/navigators/createNativeBottomTabNavigator.tsx b/packages/react-navigation/src/navigators/createNativeBottomTabNavigator.tsx index b76bdeb0..1fb96816 100644 --- a/packages/react-navigation/src/navigators/createNativeBottomTabNavigator.tsx +++ b/packages/react-navigation/src/navigators/createNativeBottomTabNavigator.tsx @@ -43,6 +43,8 @@ function NativeBottomTabNavigator({ screenOptions, tabBarActiveTintColor: customActiveTintColor, tabBarInactiveTintColor: customInactiveTintColor, + onSearchFocusChange, + onSearchTextChange, ...rest }: NativeBottomTabNavigatorProps) { const { colors } = useTheme(); @@ -77,6 +79,8 @@ function NativeBottomTabNavigator({ ).name; }} + getSearchable={({ route }) => descriptors[route.key]?.options.searchable} + getNavigationBarToolbarStyle={({ route }) => + descriptors[route.key]?.options.navigationBarToolbarStyle + } getBadge={({ route }) => descriptors[route.key]?.options.tabBarBadge} getBadgeBackgroundColor={({ route }) => descriptors[route.key]?.options.tabBarBadgeBackgroundColor From 3793de69fdad376d7e48c3f87e97ed84ab029b33 Mon Sep 17 00:00:00 2001 From: alex Date: Wed, 17 Dec 2025 13:26:48 +1100 Subject: [PATCH 2/2] fix: ipad layout --- .../react-native-bottom-tabs/ios/TabView/NewTabView.swift | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/react-native-bottom-tabs/ios/TabView/NewTabView.swift b/packages/react-native-bottom-tabs/ios/TabView/NewTabView.swift index d7901482..e4c116f7 100644 --- a/packages/react-native-bottom-tabs/ios/TabView/NewTabView.swift +++ b/packages/react-native-bottom-tabs/ios/TabView/NewTabView.swift @@ -41,7 +41,7 @@ struct NewTabView: AnyTabView { .tabAppear(using: context) .hideTabBar(props.tabBarHidden) .toolbar(tabData.navigationBarToolbarStyle.convert(), for: .navigationBar) - .searchable(text: $query) + .searchFocused($focused) .onChange(of: focused){ newValue in onSearchFocusChange(newValue) @@ -49,7 +49,9 @@ struct NewTabView: AnyTabView { .onChange(of: query) { newValue in onSearchTextChange(newValue) } - } + + }.navigationViewStyle(StackNavigationViewStyle()) + .searchable(text: $query) }else{ RepresentableView(view: child.view) .ignoresSafeArea(.container, edges: .all)