Skip to content

Commit 6bacf33

Browse files
authored
Fix button padding not being applied correctly on the new arch (#3106)
## Description Fixes #3100 Updates the logic for applying the layout metrics, which needs to be customized due to nested structure of the button on the new architecture - instead of being just a button view, it's a button view inside a custom `ViewComponentView`. Previously all metrics were applied to the wrapper view (including padding and border insets) which caused the button to be offset in the wrapper and it's content was offset again (due to children being mounted under the button instead of the wrapper and their layout metrics containing frame position). This PR changes that so that insets are not applied to the wrapper view at all and the button always fills the container. This way the layout of the children remains correct. ## Test plan Tested on the FabricExample app and on the reproducer from the issue.
1 parent 195221e commit 6bacf33

File tree

1 file changed

+35
-0
lines changed

1 file changed

+35
-0
lines changed

apple/RNGestureHandlerButtonComponentView.mm

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,41 @@ - (void)unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)childCompo
5050
[_buttonView unmountChildComponentView:childComponentView index:index];
5151
}
5252

53+
- (LayoutMetrics)buildWrapperMetrics:(const LayoutMetrics &)metrics
54+
{
55+
LayoutMetrics result = metrics;
56+
result.borderWidth = EdgeInsets::ZERO;
57+
result.contentInsets = EdgeInsets::ZERO;
58+
return result;
59+
}
60+
61+
- (LayoutMetrics)buildButtonMetrics:(const LayoutMetrics &)metrics
62+
{
63+
LayoutMetrics result = metrics;
64+
result.frame.origin = {0, 0};
65+
return result;
66+
}
67+
68+
- (void)updateLayoutMetrics:(const facebook::react::LayoutMetrics &)layoutMetrics
69+
oldLayoutMetrics:(const facebook::react::LayoutMetrics &)oldLayoutMetrics
70+
{
71+
// due to nested structure of Button and ComponentView, layout metrics for both
72+
// need to be modified:
73+
// - wrapper shouldn't have any insets as they should be applied to the button
74+
// so that it can intercept touches on padding and borders, applying them
75+
// twice breaks expected layout
76+
// - frame origin needs to be zeroes on metrics of the button as it should fill
77+
// the entirety of the wrapper component
78+
const LayoutMetrics wrapperMetrics = [self buildWrapperMetrics:layoutMetrics];
79+
const LayoutMetrics oldWrapperMetrics = [self buildWrapperMetrics:oldLayoutMetrics];
80+
81+
const LayoutMetrics buttonMetrics = [self buildButtonMetrics:layoutMetrics];
82+
const LayoutMetrics oldbuttonMetrics = [self buildButtonMetrics:oldLayoutMetrics];
83+
84+
[super updateLayoutMetrics:wrapperMetrics oldLayoutMetrics:oldWrapperMetrics];
85+
[_buttonView updateLayoutMetrics:buttonMetrics oldLayoutMetrics:oldbuttonMetrics];
86+
}
87+
5388
#pragma mark - RCTComponentViewProtocol
5489

5590
+ (ComponentDescriptorProvider)componentDescriptorProvider

0 commit comments

Comments
 (0)