Skip to content

Commit aad6884

Browse files
committed
feat: implement useBottomTabBarHeight
1 parent 153f5f7 commit aad6884

File tree

12 files changed

+217
-74
lines changed

12 files changed

+217
-74
lines changed

apps/example/ios/Podfile.lock

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1209,7 +1209,7 @@ PODS:
12091209
- ReactCommon/turbomodule/bridging
12101210
- ReactCommon/turbomodule/core
12111211
- Yoga
1212-
- react-native-bottom-tabs (0.5.2):
1212+
- react-native-bottom-tabs (0.6.0):
12131213
- DoubleConversion
12141214
- glog
12151215
- RCT-Folly (= 2024.01.01.00)
@@ -1222,7 +1222,7 @@ PODS:
12221222
- React-graphics
12231223
- React-ImageManager
12241224
- React-jsi
1225-
- react-native-bottom-tabs/common (= 0.5.2)
1225+
- react-native-bottom-tabs/common (= 0.6.0)
12261226
- React-NativeModulesApple
12271227
- React-RCTFabric
12281228
- React-rendererdebug
@@ -1234,7 +1234,7 @@ PODS:
12341234
- SDWebImageSVGCoder (>= 1.7.0)
12351235
- SwiftUIIntrospect (~> 1.0)
12361236
- Yoga
1237-
- react-native-bottom-tabs/common (0.5.2):
1237+
- react-native-bottom-tabs/common (0.6.0):
12381238
- DoubleConversion
12391239
- glog
12401240
- RCT-Folly (= 2024.01.01.00)
@@ -1945,7 +1945,7 @@ SPEC CHECKSUMS:
19451945
React-logger: d79b704bf215af194f5213a6b7deec50ba8e6a9b
19461946
React-Mapbuffer: b982d5bba94a8bc073bda48f0d27c9b28417fae3
19471947
React-microtasksnativemodule: 8fa285fed833a04a754bf575f8ded65fc240b88d
1948-
react-native-bottom-tabs: 402d19b4a55e6e17c78736a9dd2592cd9864881e
1948+
react-native-bottom-tabs: c17ddaf86c160134349c6325e020c1f38ee5f743
19491949
react-native-safe-area-context: 73505107f7c673cd550a561aeb6271f152c483b6
19501950
React-nativeconfig: 8c83d992b9cc7d75b5abe262069eaeea4349f794
19511951
React-NativeModulesApple: b8465afc883f5bf3fe8bac3767e394d581a5f123
@@ -1982,8 +1982,8 @@ SPEC CHECKSUMS:
19821982
SDWebImageSVGCoder: 15a300a97ec1c8ac958f009c02220ac0402e936c
19831983
SocketRocket: abac6f5de4d4d62d24e11868d7a2f427e0ef940d
19841984
SwiftUIIntrospect: fee9aa07293ee280373a591e1824e8ddc869ba5d
1985-
Yoga: 055f92ad73f8c8600a93f0e25ac0b2344c3b07e6
1985+
Yoga: aa3df615739504eebb91925fc9c58b4922ea9a08
19861986

19871987
PODFILE CHECKSUM: 1c1dbca3e400ef935aa9a150cb2dcb58fb8c4536
19881988

1989-
COCOAPODS: 1.15.2
1989+
COCOAPODS: 1.14.3
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import * as React from 'react';
2+
import { View, Text, StyleSheet } from 'react-native';
3+
4+
type MusicControlProps = {
5+
bottomOffset: number;
6+
};
7+
8+
export const MusicControl: React.FC<MusicControlProps> = ({ bottomOffset }) => {
9+
return (
10+
<View
11+
style={[
12+
styles.musicControlContainer,
13+
{
14+
bottom: bottomOffset + 10,
15+
},
16+
]}
17+
>
18+
<View style={styles.musicControlContent}>
19+
<View style={styles.songInfo}>
20+
<Text style={styles.songTitle} numberOfLines={1}>
21+
Currently Playing Song
22+
</Text>
23+
</View>
24+
<View style={styles.controls}>
25+
<Text style={styles.controlButton}></Text>
26+
<Text style={styles.controlButton}></Text>
27+
</View>
28+
</View>
29+
</View>
30+
);
31+
};
32+
33+
const styles = StyleSheet.create({
34+
musicControlContainer: {
35+
position: 'absolute',
36+
left: 15,
37+
right: 15,
38+
borderRadius: 18,
39+
height: 55,
40+
backgroundColor: '#fff',
41+
shadowColor: '#000',
42+
shadowOffset: {
43+
width: 0,
44+
height: 4,
45+
},
46+
shadowOpacity: 0.25,
47+
shadowRadius: 5,
48+
elevation: 8,
49+
},
50+
musicControlContent: {
51+
flex: 1,
52+
flexDirection: 'row',
53+
alignItems: 'center',
54+
paddingHorizontal: 16,
55+
paddingVertical: 8,
56+
},
57+
songInfo: {
58+
flex: 1,
59+
marginRight: 16,
60+
},
61+
songTitle: {
62+
fontSize: 14,
63+
fontWeight: '600',
64+
color: '#000',
65+
},
66+
controls: {
67+
flexDirection: 'row',
68+
alignItems: 'center',
69+
},
70+
controlButton: {
71+
fontSize: 24,
72+
paddingHorizontal: 12,
73+
color: '#000',
74+
},
75+
});

apps/example/src/Screens/Contacts.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import {
99
Text,
1010
View,
1111
} from 'react-native';
12+
import { useBottomTabBarHeight } from 'react-native-bottom-tabs';
13+
import { MusicControl } from '../Components/MusicControl';
1214

1315
type Item = { name: string; number: number };
1416

@@ -97,6 +99,7 @@ export function Contacts({ query, ...rest }: Props) {
9799
console.log(Platform.OS, ' Rendering Contacts');
98100
const renderItem = ({ item }: { item: Item }) => <ContactItem item={item} />;
99101

102+
const tabBarHeight = useBottomTabBarHeight();
100103
const ref = React.useRef<FlatList>(null);
101104
useScrollToTop(ref);
102105

@@ -117,6 +120,7 @@ export function Contacts({ query, ...rest }: Props) {
117120
renderItem={renderItem}
118121
ItemSeparatorComponent={ItemSeparator}
119122
/>
123+
<MusicControl bottomOffset={tabBarHeight} />
120124
</SafeAreaView>
121125
);
122126
}

packages/react-native-bottom-tabs/ios/Fabric/RCTTabViewComponentView.mm

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,15 @@ - (void)onLongPressWithKey:(NSString *)key reactTag:(NSNumber *)reactTag {
223223
}
224224
}
225225

226+
- (void)onTabBarMeasuredWithHeight:(NSInteger)height reactTag:(NSNumber *)reactTag {
227+
auto eventEmitter = std::static_pointer_cast<const RNCTabViewEventEmitter>(_eventEmitter);
228+
if (eventEmitter) {
229+
eventEmitter->onTabBarMeasured(RNCTabViewEventEmitter::OnTabBarMeasured {
230+
.height = (int)height
231+
});
232+
}
233+
}
234+
226235
@end
227236

228237
Class<RCTComponentViewProtocol> RNCTabViewCls(void)

packages/react-native-bottom-tabs/ios/RCTTabViewViewManager.mm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ - (instancetype)init
3030
RCT_EXPORT_VIEW_PROPERTY(items, NSArray)
3131
RCT_EXPORT_VIEW_PROPERTY(onPageSelected, RCTDirectEventBlock)
3232
RCT_EXPORT_VIEW_PROPERTY(onTabLongPress, RCTDirectEventBlock)
33+
RCT_EXPORT_VIEW_PROPERTY(onTabBarMeasured, RCTDirectEventBlock)
3334
RCT_EXPORT_VIEW_PROPERTY(selectedPage, NSString)
3435
RCT_EXPORT_VIEW_PROPERTY(tabViewStyle, NSString)
3536
RCT_EXPORT_VIEW_PROPERTY(icons, NSArray<RCTImageSource *>);

packages/react-native-bottom-tabs/ios/TabViewImpl.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,11 @@ struct RepresentableView: UIViewRepresentable {
5555
*/
5656
struct TabViewImpl: View {
5757
@ObservedObject var props: TabViewProps
58-
var onSelect: (_ key: String) -> Void
59-
var onLongPress: (_ key: String) -> Void
6058
@Weak var tabBar: UITabBar?
6159

60+
var onSelect: (_ key: String) -> Void
61+
var onLongPress: (_ key: String) -> Void
62+
var onTabBarMeasured: (_ height: Int) -> Void
6263

6364
var body: some View {
6465
TabView(selection: $props.selectedPage) {
@@ -83,6 +84,9 @@ struct TabViewImpl: View {
8384
#endif
8485
.introspectTabView(closure: { tabController in
8586
tabBar = tabController.tabBar
87+
onTabBarMeasured(
88+
Int(tabController.tabBar.frame.size.height)
89+
)
8690
})
8791
.configureAppearance(props: props, tabBar: tabBar)
8892
.tintColor(props.selectedActiveTintColor)

packages/react-native-bottom-tabs/ios/TabViewProvider.swift

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import SDWebImageSVGCoder
1111
@objc public let sfSymbol: String
1212
@objc public let activeTintColor: UIColor?
1313
@objc public let hidden: Bool
14-
14+
1515
@objc
1616
public init(
1717
key: String,
@@ -34,6 +34,7 @@ import SDWebImageSVGCoder
3434
@objc public protocol TabViewProviderDelegate {
3535
func onPageSelected(key: String, reactTag: NSNumber?)
3636
func onLongPress(key: String, reactTag: NSNumber?)
37+
func onTabBarMeasured(height: Int, reactTag: NSNumber?)
3738
}
3839

3940
@objc public class TabViewProvider: UIView {
@@ -46,6 +47,7 @@ import SDWebImageSVGCoder
4647
@objc var onPageSelected: RCTDirectEventBlock?
4748

4849
@objc var onTabLongPress: RCTDirectEventBlock?
50+
@objc var onTabBarMeasured: RCTDirectEventBlock?
4951

5052
@objc public var icons: NSArray? {
5153
didSet {
@@ -131,19 +133,19 @@ import SDWebImageSVGCoder
131133
props.inactiveTintColor = inactiveTintColor
132134
}
133135
}
134-
136+
135137
@objc public var fontFamily: NSString? {
136138
didSet {
137139
props.fontFamily = fontFamily as? String
138140
}
139141
}
140-
142+
141143
@objc public var fontWeigth: NSString? {
142144
didSet {
143145
props.fontWeight = fontWeigth as? String
144146
}
145147
}
146-
148+
147149
@objc public var fontSize: NSNumber? {
148150
didSet {
149151
props.fontSize = fontSize as? Int
@@ -182,7 +184,10 @@ import SDWebImageSVGCoder
182184
self.delegate?.onPageSelected(key: key, reactTag: self.reactTag)
183185
} onLongPress: { key in
184186
self.delegate?.onLongPress(key: key, reactTag: self.reactTag)
187+
} onTabBarMeasured: { height in
188+
self.delegate?.onTabBarMeasured(height: height, reactTag: self.reactTag)
185189
})
190+
186191
if let hostingController = self.hostingController, let parentViewController = reactViewController() {
187192
parentViewController.addChild(hostingController)
188193
addSubview(hostingController.view)
@@ -196,27 +201,27 @@ import SDWebImageSVGCoder
196201
// TODO: Diff the arrays and update only changed items.
197202
// Now if the user passes `unfocusedIcon` we update every item.
198203
guard let imageSources = icons as? [RCTImageSource?] else { return }
199-
204+
200205
for (index, imageSource) in imageSources.enumerated() {
201206
guard let imageSource = imageSource,
202207
let url = imageSource.request.url else { continue }
203-
208+
204209
let isSVG = url.pathExtension.lowercased() == "svg"
205-
210+
206211
var options: SDWebImageOptions = [.continueInBackground,
207212
.scaleDownLargeImages,
208213
.avoidDecodeImage,
209214
.highPriority]
210-
215+
211216
if isSVG {
212217
options.insert(.decodeFirstFrameOnly)
213218
}
214-
219+
215220
let context: [SDWebImageContextOption: Any]? = isSVG ? [
216221
.imageThumbnailPixelSize: iconSize,
217222
.imagePreserveAspectRatio: true
218223
] : nil
219-
224+
220225
SDWebImageManager.shared.loadImage(
221226
with: url,
222227
options: options,

0 commit comments

Comments
 (0)