Skip to content

Commit 0eb5e65

Browse files
Mazin Zakariameta-codesync[bot]
authored andcommitted
Fix transformOrigin calculating based on incorrect value (#55796)
Summary: Pull Request resolved: #55796 Changelog: [iOS] [Fixed] - Fixed `transformOrigin` using stale layout dimensions from recycled views, causing incorrect transform positioning Reviewed By: jorge-cab, javache Differential Revision: D94628804 fbshipit-source-id: da0858fd5ccaf2df5b3edd91bdc22716f2650b10
1 parent 21fae86 commit 0eb5e65

1 file changed

Lines changed: 12 additions & 1 deletion

File tree

packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,12 @@ - (void)updateLayoutMetrics:(const LayoutMetrics &)layoutMetrics
566566
// re-applying individual sub-values which weren't changed.
567567
[super updateLayoutMetrics:layoutMetrics oldLayoutMetrics:_layoutMetrics];
568568

569+
// Capture the frame size that was used by updateProps to resolve the
570+
// transform, before overwriting _layoutMetrics. This is important because
571+
// _layoutMetrics may be stale (e.g., from a recycled view) and differ from
572+
// the oldLayoutMetrics parameter (which comes from the shadow tree).
573+
auto previousFrameSize = _layoutMetrics.frame.size;
574+
569575
_layoutMetrics = layoutMetrics;
570576
_needsInvalidateLayer = YES;
571577

@@ -583,8 +589,12 @@ - (void)updateLayoutMetrics:(const LayoutMetrics &)layoutMetrics
583589
_backgroundColorLayer.frame = CGRectMake(0, 0, self.layer.bounds.size.width, self.layer.bounds.size.height);
584590
}
585591

592+
// Recompute the transform whenever the layout size differs from what was
593+
// used in updateProps. Using previousFrameSize (the stored _layoutMetrics)
594+
// instead of the oldLayoutMetrics parameter ensures correctness even when
595+
// the view was recycled with stale dimensions.
586596
if ((_props->transformOrigin.isSet() || !_props->transform.operations.empty()) &&
587-
layoutMetrics.frame.size != oldLayoutMetrics.frame.size) {
597+
layoutMetrics.frame.size != previousFrameSize) {
588598
auto newTransform = _props->resolveTransform(layoutMetrics);
589599
self.layer.transform = RCTCATransform3DFromTransformMatrix(newTransform);
590600
}
@@ -654,6 +664,7 @@ - (void)prepareForRecycle
654664
_isJSResponder = NO;
655665
_removeClippedSubviews = NO;
656666
_reactSubviews = [NSMutableArray new];
667+
_layoutMetrics = {};
657668
}
658669

659670
- (void)setPropKeysManagedByAnimated_DO_NOT_USE_THIS_IS_BROKEN:(NSSet<NSString *> *_Nullable)props

0 commit comments

Comments
 (0)