Skip to content

Commit 50d0fc9

Browse files
committed
Send update to ST from Subview after layouting its subviews & small
refactor (method naming)
1 parent 22e632b commit 50d0fc9

File tree

3 files changed

+66
-17
lines changed

3 files changed

+66
-17
lines changed

ios/RNSScreenStackHeaderConfig.mm

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,8 +231,7 @@ - (void)updateHeaderStateInShadowTreeInContextOfNavigationBar:(nullable UINaviga
231231

232232
[self updateHeaderConfigState:navigationBar.frame.size];
233233
for (RNSScreenStackHeaderSubview *subview in self.reactSubviews) {
234-
CGRect frameInNavBarCoordinates = [subview convertRect:subview.frame toView:navigationBar];
235-
[subview updateHeaderSubviewFrameInShadowTree:frameInNavBarCoordinates];
234+
[subview updateShadowStateInContextOfAncestorView:navigationBar];
236235
}
237236
}
238237
#else

ios/RNSScreenStackHeaderSubview.h

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,30 @@ NS_ASSUME_NONNULL_BEGIN
2121
@property (nonatomic, weak) UIView *reactSuperview;
2222

2323
#ifdef RCT_NEW_ARCH_ENABLED
24-
- (void)updateHeaderSubviewFrameInShadowTree:(CGRect)frame;
24+
/**
25+
* Updates state of the header subview shadow node in shadow tree.
26+
* This method updates state of header subview shadow node only.
27+
*/
28+
- (void)updateShadowStateWithFrame:(CGRect)frame;
29+
30+
/**
31+
* Updates state of the header subview shadow node in shadow tree in context of given ancestor view.
32+
* This method updates state of header subview shadow node only.
33+
*
34+
* @param ancestorView - ancestor view in relation to which, the frame send in state update is computed; if this is
35+
* `nil` the method does nothing.
36+
*/
37+
- (void)updateShadowStateInContextOfAncestorView:(nullable UIView *)ancestorView;
38+
39+
/**
40+
* Updates state of the header subview shadow node in shadow tree in context of given ancestor view.
41+
* This method updates state of header subview shadow node only.
42+
*
43+
* @param ancestorView ancestor view in relation to which, the frame send in state update is computed; if this is
44+
* `nil` the method does nothing.
45+
* @param frame source frame, which will be transformed in relation to `ancestorView`.
46+
*/
47+
- (void)updateShadowStateInContextOfAncestorView:(nullable UIView *)ancestorView withFrame:(CGRect)frame;
2548
#endif
2649

2750
@end

ios/RNSScreenStackHeaderSubview.mm

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ - (nullable RNSScreenStackHeaderConfig *)getHeaderConfig
3939
return headerConfig;
4040
}
4141

42+
- (nullable UINavigationBar *)findNavigationBar
43+
{
44+
return [[[[[self getHeaderConfig] screenView] reactViewController] navigationController] navigationBar];
45+
}
46+
4247
// We're forcing the navigation controller's view to re-layout
4348
// see: https://github.com/software-mansion/react-native-screens/pull/2385
4449
- (void)layoutNavigationBar
@@ -68,6 +73,42 @@ - (void)layoutNavigationBar
6873

6974
#pragma mark - Fabric specific
7075

76+
- (void)updateShadowStateInContextOfAncestorView:(nullable UIView *)ancestorView withFrame:(CGRect)frame
77+
{
78+
if (ancestorView == nil) {
79+
// We can not compute valid value
80+
return;
81+
}
82+
83+
CGRect convertedFrame = [self convertRect:frame toView:ancestorView];
84+
[self updateShadowStateWithFrame:convertedFrame];
85+
}
86+
87+
- (void)updateShadowStateInContextOfAncestorView:(nullable UIView *)ancestorView
88+
{
89+
[self updateShadowStateInContextOfAncestorView:ancestorView withFrame:self.frame];
90+
}
91+
92+
- (void)updateShadowStateWithFrame:(CGRect)frame
93+
{
94+
if (_state == nullptr) {
95+
return;
96+
}
97+
98+
if (!CGRectEqualToRect(frame, _lastScheduledFrame)) {
99+
auto newState =
100+
react::RNSScreenStackHeaderSubviewState(RCTSizeFromCGSize(frame.size), RCTPointFromCGPoint(frame.origin));
101+
_state->updateState(std::move(newState));
102+
_lastScheduledFrame = frame;
103+
}
104+
}
105+
106+
- (void)layoutSubviews
107+
{
108+
[super layoutSubviews];
109+
[self updateShadowStateInContextOfAncestorView:[self findNavigationBar]];
110+
}
111+
71112
// Needed because of this: https://github.com/facebook/react-native/pull/37274
72113
+ (void)load
73114
{
@@ -138,20 +179,6 @@ - (void)updateState:(const facebook::react::State::Shared &)state
138179
{
139180
_state = std::static_pointer_cast<const react::RNSScreenStackHeaderSubviewShadowNode::ConcreteState>(state);
140181
}
141-
142-
- (void)updateHeaderSubviewFrameInShadowTree:(CGRect)frame
143-
{
144-
if (_state == nullptr) {
145-
return;
146-
}
147-
148-
if (!CGRectEqualToRect(frame, _lastScheduledFrame)) {
149-
auto newState =
150-
react::RNSScreenStackHeaderSubviewState(RCTSizeFromCGSize(frame.size), RCTPointFromCGPoint(frame.origin));
151-
_state->updateState(std::move(newState));
152-
_lastScheduledFrame = frame;
153-
}
154-
}
155182
#else // RCT_NEW_ARCH_ENABLED
156183
#pragma mark - Paper specific
157184

0 commit comments

Comments
 (0)