Skip to content

Commit ee427b7

Browse files
authored
fix: improve subview management on iOS (#404)
1 parent 9940e8e commit ee427b7

File tree

4 files changed

+31
-24
lines changed

4 files changed

+31
-24
lines changed

.changeset/young-coats-start.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'react-native-bottom-tabs': patch
3+
---
4+
5+
fix: improve subview management on iOS

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

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ @interface RCTTabViewComponentView () <RCTRNCTabViewViewProtocol, TabViewProvide
5757

5858
@implementation RCTTabViewComponentView {
5959
TabViewProvider *_tabViewProvider;
60-
NSMutableArray<PlatformView *> *_reactSubviews;
6160
}
6261

6362
+ (ComponentDescriptorProvider)componentDescriptorProvider
@@ -69,7 +68,6 @@ - (instancetype)initWithFrame:(CGRect)frame
6968
{
7069
if (self = [super initWithFrame:frame]) {
7170
static const auto defaultProps = std::make_shared<const RNCTabViewProps>();
72-
_reactSubviews = [NSMutableArray new];
7371
_tabViewProvider = [[TabViewProvider alloc] initWithDelegate:self];
7472
self.contentView = _tabViewProvider;
7573
_props = defaultProps;
@@ -84,24 +82,12 @@ + (BOOL)shouldBeRecycled
8482
return NO;
8583
}
8684

87-
- (void)layoutSubviews {
88-
[super layoutSubviews];
89-
_tabViewProvider.children = [self reactSubviews];
90-
}
91-
92-
- (NSArray<PlatformView *> *)reactSubviews
93-
{
94-
return _reactSubviews;
95-
}
96-
9785
- (void)mountChildComponentView:(PlatformView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index {
98-
[_reactSubviews insertObject:childComponentView atIndex:index];
99-
_tabViewProvider.children = [self reactSubviews];
86+
[_tabViewProvider insertChild:childComponentView atIndex:index];
10087
}
10188

10289
- (void)unmountChildComponentView:(PlatformView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index {
103-
[_reactSubviews removeObjectAtIndex:index];
104-
90+
[_tabViewProvider removeChildAtIndex:index];
10591
[childComponentView removeFromSuperview];
10692
}
10793

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,28 @@ import SwiftUI
22

33
/**
44
Helper used to render UIView inside of SwiftUI.
5+
Wraps each view with an additional wrapper to avoid directly managing React Native views.
6+
This solves issues where the layout would have weird artifacts..
57
*/
68
struct RepresentableView: PlatformViewRepresentable {
79
var view: PlatformView
810

911
#if os(macOS)
1012

1113
func makeNSView(context: Context) -> PlatformView {
12-
view
14+
let wrapper = NSView()
15+
wrapper.addSubview(view)
16+
return wrapper
1317
}
1418

1519
func updateNSView(_ nsView: PlatformView, context: Context) {}
1620

1721
#else
1822

1923
func makeUIView(context: Context) -> PlatformView {
20-
view
24+
let wrapper = UIView()
25+
wrapper.addSubview(view)
26+
return wrapper
2127
}
2228

2329
func updateUIView(_ uiView: PlatformView, context: Context) {}

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

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,6 @@ public final class TabInfo: NSObject {
6363
}
6464
}
6565

66-
@objc public var children: [PlatformView] = [] {
67-
didSet {
68-
props.children = children
69-
}
70-
}
71-
7266
@objc public var sidebarAdaptable: Bool = false {
7367
didSet {
7468
props.sidebarAdaptable = sidebarAdaptable
@@ -221,6 +215,22 @@ public final class TabInfo: NSObject {
221215
#endif
222216
}
223217
}
218+
219+
@objc(insertChild:atIndex:)
220+
public func insertChild(_ child: UIView, at index: Int) {
221+
guard index >= 0 && index <= props.children.count else {
222+
return
223+
}
224+
props.children.insert(child, at: index)
225+
}
226+
227+
@objc(removeChildAtIndex:)
228+
public func removeChild(at index: Int) {
229+
guard index >= 0 && index < props.children.count else {
230+
return
231+
}
232+
props.children.remove(at: index)
233+
}
224234

225235
private func loadIcons(_ icons: NSArray?) {
226236
// TODO: Diff the arrays and update only changed items.

0 commit comments

Comments
 (0)