Skip to content

Commit d933ccb

Browse files
committed
feat: new arch
1 parent 1e99a7d commit d933ccb

13 files changed

+512
-110
lines changed

example/ios/Podfile.lock

Lines changed: 92 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1232,7 +1232,71 @@ PODS:
12321232
- SwiftUIIntrospect (~> 1.0)
12331233
- Yoga
12341234
- react-native-safe-area-context (4.11.0):
1235+
- DoubleConversion
1236+
- glog
1237+
- RCT-Folly (= 2024.01.01.00)
1238+
- RCTRequired
1239+
- RCTTypeSafety
1240+
- React-Core
1241+
- React-debug
1242+
- React-Fabric
1243+
- React-featureflags
1244+
- React-graphics
1245+
- React-ImageManager
1246+
- React-jsi
1247+
- react-native-safe-area-context/common (= 4.11.0)
1248+
- react-native-safe-area-context/fabric (= 4.11.0)
1249+
- React-NativeModulesApple
1250+
- React-RCTFabric
1251+
- React-rendererdebug
1252+
- React-utils
1253+
- ReactCodegen
1254+
- ReactCommon/turbomodule/bridging
1255+
- ReactCommon/turbomodule/core
1256+
- Yoga
1257+
- react-native-safe-area-context/common (4.11.0):
1258+
- DoubleConversion
1259+
- glog
1260+
- RCT-Folly (= 2024.01.01.00)
1261+
- RCTRequired
1262+
- RCTTypeSafety
1263+
- React-Core
1264+
- React-debug
1265+
- React-Fabric
1266+
- React-featureflags
1267+
- React-graphics
1268+
- React-ImageManager
1269+
- React-jsi
1270+
- React-NativeModulesApple
1271+
- React-RCTFabric
1272+
- React-rendererdebug
1273+
- React-utils
1274+
- ReactCodegen
1275+
- ReactCommon/turbomodule/bridging
1276+
- ReactCommon/turbomodule/core
1277+
- Yoga
1278+
- react-native-safe-area-context/fabric (4.11.0):
1279+
- DoubleConversion
1280+
- glog
1281+
- RCT-Folly (= 2024.01.01.00)
1282+
- RCTRequired
1283+
- RCTTypeSafety
12351284
- React-Core
1285+
- React-debug
1286+
- React-Fabric
1287+
- React-featureflags
1288+
- React-graphics
1289+
- React-ImageManager
1290+
- React-jsi
1291+
- react-native-safe-area-context/common
1292+
- React-NativeModulesApple
1293+
- React-RCTFabric
1294+
- React-rendererdebug
1295+
- React-utils
1296+
- ReactCodegen
1297+
- ReactCommon/turbomodule/bridging
1298+
- ReactCommon/turbomodule/core
1299+
- Yoga
12361300
- React-nativeconfig (0.75.3)
12371301
- React-NativeModulesApple (0.75.3):
12381302
- glog
@@ -1491,6 +1555,7 @@ PODS:
14911555
- React-ImageManager
14921556
- React-jsi
14931557
- React-NativeModulesApple
1558+
- React-RCTAppDelegate
14941559
- React-RCTFabric
14951560
- React-rendererdebug
14961561
- React-utils
@@ -1524,6 +1589,29 @@ PODS:
15241589
- ReactCommon/turbomodule/core
15251590
- Yoga
15261591
- RNScreens (3.34.0):
1592+
- DoubleConversion
1593+
- glog
1594+
- RCT-Folly (= 2024.01.01.00)
1595+
- RCTRequired
1596+
- RCTTypeSafety
1597+
- React-Core
1598+
- React-debug
1599+
- React-Fabric
1600+
- React-featureflags
1601+
- React-graphics
1602+
- React-ImageManager
1603+
- React-jsi
1604+
- React-NativeModulesApple
1605+
- React-RCTFabric
1606+
- React-RCTImage
1607+
- React-rendererdebug
1608+
- React-utils
1609+
- ReactCodegen
1610+
- ReactCommon/turbomodule/bridging
1611+
- ReactCommon/turbomodule/core
1612+
- RNScreens/common (= 3.34.0)
1613+
- Yoga
1614+
- RNScreens/common (3.34.0):
15271615
- DoubleConversion
15281616
- glog
15291617
- RCT-Folly (= 2024.01.01.00)
@@ -1578,6 +1666,7 @@ DEPENDENCIES:
15781666
- React-idlecallbacksnativemodule (from `../node_modules/react-native/ReactCommon/react/nativemodule/idlecallbacks`)
15791667
- React-ImageManager (from `../node_modules/react-native/ReactCommon/react/renderer/imagemanager/platform/ios`)
15801668
- React-jsc (from `../node_modules/react-native/ReactCommon/jsc`)
1669+
- React-jsc/Fabric (from `../node_modules/react-native/ReactCommon/jsc`)
15811670
- React-jserrorhandler (from `../node_modules/react-native/ReactCommon/jserrorhandler`)
15821671
- React-jsi (from `../node_modules/react-native/ReactCommon/jsi`)
15831672
- React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`)
@@ -1804,9 +1893,9 @@ SPEC CHECKSUMS:
18041893
React-performancetimeline: d15a723422ed500f47cb271f3175abbeb217f5ba
18051894
React-RCTActionSheet: cb2b38a53d03ec22f1159c89667b86c2c490d92d
18061895
React-RCTAnimation: 6836c87c7364f471e9077fda80b7349bc674be33
1807-
React-RCTAppDelegate: fb2037d3472bda5c31ea16a04cc48e19fe81c792
1896+
React-RCTAppDelegate: 8939a29da847bc51a01264d020a58d9d5035e119
18081897
React-RCTBlob: 984c80df29f3b3e3193bfbc2768bd302c889719b
1809-
React-RCTFabric: 5e691cfb4cd3a9060ddbfb04916284c3c6a933e8
1898+
React-RCTFabric: 4bb022567aacec7417d04741cba7e7baaeec6add
18101899
React-RCTImage: 1b2c2c1716db859ffff2d7a06a30b0ec5c677fc5
18111900
React-RCTLinking: 59c07577767e705b0ab95d11e5ad74c61bf2a022
18121901
React-RCTNetwork: f9a827e7d6bc428e0d99cd1fbe0427854354b8c1
@@ -1834,4 +1923,4 @@ SPEC CHECKSUMS:
18341923

18351924
PODFILE CHECKSUM: 539add55dc6c2e7f9754e288b1ce4fd8583819ae
18361925

1837-
COCOAPODS: 1.15.2
1926+
COCOAPODS: 1.14.3

ios/Extensions.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,13 @@ extension UIView {
2727
])
2828
}
2929
}
30+
31+
extension UIImage {
32+
func resizeImageTo(size: CGSize) -> UIImage? {
33+
UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
34+
self.draw(in: CGRect(origin: CGPoint.zero, size: size))
35+
let resizedImage = UIGraphicsGetImageFromCurrentImageContext()!
36+
UIGraphicsEndImageContext()
37+
return resizedImage
38+
}
39+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#ifdef RCT_NEW_ARCH_ENABLED
2+
#import <React/RCTViewComponentView.h>
3+
#import <UIKit/UIKit.h>
4+
5+
NS_ASSUME_NONNULL_BEGIN
6+
7+
@interface RCTTabViewComponentView: RCTViewComponentView
8+
@end
9+
10+
NS_ASSUME_NONNULL_END
11+
12+
#endif /* RCT_NEW_ARCH_ENABLED */
Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
#ifdef RCT_NEW_ARCH_ENABLED
2+
#import "RCTTabViewComponentView.h"
3+
4+
#import <react/renderer/components/RNCTabViewSpec/ComponentDescriptors.h>
5+
#import <react/renderer/components/RNCTabViewSpec/EventEmitters.h>
6+
#import <react/renderer/components/RNCTabViewSpec/Props.h>
7+
#import <react/renderer/components/RNCTabViewSpec/RCTComponentViewHelpers.h>
8+
9+
#import <React/RCTFabricComponentsPlugins.h>
10+
11+
#if __has_include("react_native_bottom_tabs/react_native_bottom_tabs-Swift.h")
12+
#import "react_native_bottom_tabs/react_native_bottom_tabs-Swift.h"
13+
#else
14+
#import "react_native_bottom_tabs-Swift.h"
15+
#endif
16+
17+
#import <React/RCTImageLoader.h>
18+
#import <React/RCTImageSource.h>
19+
#import <React/RCTBridge+Private.h>
20+
#import "RCTImagePrimitivesConversions.h"
21+
#import "RCTConversions.h"
22+
23+
24+
using namespace facebook::react;
25+
26+
@interface RCTTabViewComponentView () <RCTRNCTabViewViewProtocol, TabViewProviderDelegate> {
27+
}
28+
29+
@end
30+
31+
@implementation RCTTabViewComponentView {
32+
TabViewProvider *_tabViewProvider;
33+
NSMutableArray<UIView *> *_reactSubviews;
34+
}
35+
36+
+ (ComponentDescriptorProvider)componentDescriptorProvider
37+
{
38+
return concreteComponentDescriptorProvider<RNCTabViewComponentDescriptor>();
39+
}
40+
41+
- (instancetype)initWithFrame:(CGRect)frame
42+
{
43+
if (self = [super initWithFrame:frame]) {
44+
static const auto defaultProps = std::make_shared<const RNCTabViewProps>();
45+
_reactSubviews = [NSMutableArray new];
46+
RCTImageLoader *imageLoader = [[RCTBridge currentBridge] moduleForName:@"ImageLoader"];
47+
_tabViewProvider = [[TabViewProvider alloc] initWithDelegate:self imageLoader:imageLoader];
48+
self.contentView = _tabViewProvider;
49+
_props = defaultProps;
50+
}
51+
52+
return self;
53+
}
54+
55+
// Opt out of recycling for now, it's not working properly.
56+
+ (BOOL)shouldBeRecycled
57+
{
58+
return NO;
59+
}
60+
61+
- (void)layoutSubviews {
62+
[super layoutSubviews];
63+
_tabViewProvider.children = [self reactSubviews];
64+
}
65+
66+
- (NSArray<UIView *> *)reactSubviews
67+
{
68+
return _reactSubviews;
69+
}
70+
71+
- (void)mountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index {
72+
[_reactSubviews insertObject:childComponentView atIndex:index];
73+
_tabViewProvider.children = [self reactSubviews];
74+
}
75+
76+
- (void)unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index {
77+
[_reactSubviews removeObjectAtIndex:index];
78+
79+
[childComponentView removeFromSuperview];
80+
}
81+
82+
- (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps
83+
{
84+
const auto &oldViewProps = *std::static_pointer_cast<RNCTabViewProps const>(_props);
85+
const auto &newViewProps = *std::static_pointer_cast<RNCTabViewProps const>(props);
86+
87+
if (haveTabItemsChanged(oldViewProps.items, newViewProps.items)) {
88+
_tabViewProvider.itemsData = convertItemsToArray(newViewProps.items);
89+
}
90+
91+
if (oldViewProps.translucent != newViewProps.translucent) {
92+
_tabViewProvider.translucent = newViewProps.translucent;
93+
}
94+
95+
if (oldViewProps.icons != newViewProps.icons) {
96+
auto iconsArray = [[NSMutableArray alloc] init];
97+
for (auto &source: newViewProps.icons) {
98+
auto imageSource = [[RCTImageSource alloc] initWithURLRequest:NSURLRequestFromImageSource(source) size:CGSizeMake(source.size.width, source.size.height) scale:source.scale];
99+
[iconsArray addObject:imageSource];
100+
}
101+
102+
_tabViewProvider.icons = iconsArray;
103+
}
104+
105+
if (oldViewProps.sidebarAdaptable != newViewProps.sidebarAdaptable) {
106+
_tabViewProvider.sidebarAdaptable = newViewProps.sidebarAdaptable;
107+
}
108+
109+
if (oldViewProps.disablePageAnimations != newViewProps.disablePageAnimations) {
110+
_tabViewProvider.disablePageAnimations = newViewProps.disablePageAnimations;
111+
}
112+
113+
if (oldViewProps.labeled != newViewProps.labeled) {
114+
_tabViewProvider.labeled = newViewProps.labeled;
115+
}
116+
117+
if (oldViewProps.ignoresTopSafeArea != newViewProps.ignoresTopSafeArea) {
118+
_tabViewProvider.ignoresTopSafeArea = newViewProps.ignoresTopSafeArea;
119+
}
120+
121+
if (oldViewProps.selectedPage != newViewProps.selectedPage) {
122+
_tabViewProvider.selectedPage = RCTNSStringFromString(newViewProps.selectedPage);
123+
}
124+
125+
if (oldViewProps.scrollEdgeAppearance != newViewProps.scrollEdgeAppearance) {
126+
_tabViewProvider.scrollEdgeAppearance = RCTNSStringFromString(newViewProps.scrollEdgeAppearance);
127+
}
128+
129+
if (oldViewProps.labeled != newViewProps.labeled) {
130+
_tabViewProvider.labeled = newViewProps.labeled;
131+
}
132+
133+
if (oldViewProps.barTintColor != newViewProps.barTintColor) {
134+
_tabViewProvider.barTintUIColor = RCTUIColorFromSharedColor(newViewProps.barTintColor);
135+
}
136+
137+
if (oldViewProps.activeTintColor != newViewProps.activeTintColor) {
138+
_tabViewProvider.activeTintUIColor = RCTUIColorFromSharedColor(newViewProps.activeTintColor);
139+
}
140+
141+
if (oldViewProps.inactiveTintColor != newViewProps.inactiveTintColor) {
142+
_tabViewProvider.inactiveTintUIColor = RCTUIColorFromSharedColor(newViewProps.inactiveTintColor);
143+
}
144+
145+
[super updateProps:props oldProps:oldProps];
146+
}
147+
148+
bool areTabItemsEqual(const RNCTabViewItemsStruct& lhs, const RNCTabViewItemsStruct& rhs) {
149+
return lhs.key == rhs.key &&
150+
lhs.title == rhs.title &&
151+
lhs.sfSymbol == rhs.sfSymbol &&
152+
lhs.badge == rhs.badge &&
153+
lhs.activeTintColor == rhs.activeTintColor;
154+
}
155+
156+
bool haveTabItemsChanged(const std::vector<RNCTabViewItemsStruct>& oldItems,
157+
const std::vector<RNCTabViewItemsStruct>& newItems) {
158+
159+
if (oldItems.size() != newItems.size()) {
160+
return true;
161+
}
162+
163+
for (size_t i = 0; i < oldItems.size(); ++i) {
164+
if (!areTabItemsEqual(oldItems[i], newItems[i])) {
165+
return true;
166+
}
167+
}
168+
169+
return false;
170+
}
171+
172+
NSArray* convertItemsToArray(const std::vector<RNCTabViewItemsStruct>& items) {
173+
NSMutableArray<TabInfo *> *result = [NSMutableArray array];
174+
175+
for (const auto& item : items) {
176+
auto tabInfo = [[TabInfo alloc] initWithKey:RCTNSStringFromString(item.key) title:RCTNSStringFromString(item.title) badge:RCTNSStringFromString(item.badge) sfSymbol:RCTNSStringFromString(item.sfSymbol) activeTintColor:RCTUIColorFromSharedColor(item.activeTintColor)];
177+
178+
[result addObject:tabInfo];
179+
}
180+
181+
return result;
182+
}
183+
184+
// MARK: TabViewProviderDelegate
185+
186+
- (void)onPageSelectedWithKey:(NSString *)key reactTag:(NSNumber *)reactTag {
187+
auto eventEmitter = std::static_pointer_cast<const RNCTabViewEventEmitter>(_eventEmitter);
188+
if (eventEmitter) {
189+
eventEmitter->onPageSelected(RNCTabViewEventEmitter::OnPageSelected{
190+
.key = [key cStringUsingEncoding:kCFStringEncodingUTF8]
191+
});
192+
}
193+
}
194+
195+
- (void)onLongPressWithKey:(NSString *)key reactTag:(NSNumber *)reactTag {
196+
auto eventEmitter = std::static_pointer_cast<const RNCTabViewEventEmitter>(_eventEmitter);
197+
if (eventEmitter) {
198+
eventEmitter->onTabLongPress(RNCTabViewEventEmitter::OnTabLongPress {
199+
.key = [key cStringUsingEncoding:kCFStringEncodingUTF8]
200+
});
201+
}
202+
}
203+
204+
@end
205+
206+
Class<RCTComponentViewProtocol> RNCTabViewCls(void)
207+
{
208+
return RCTTabViewComponentView.class;
209+
}
210+
211+
#endif // RCT_NEW_ARCH_ENABLED
212+
213+

0 commit comments

Comments
 (0)