Skip to content

fix(ios): resize useRenderInContext captures to width/height - #730

Merged
gre merged 1 commit into
gre:masterfrom
mkantautas:fix/render-in-context-size
Oct 24, 2026
Merged

gre merged 1 commit into
gre:masterfrom
mkantautas:fix/render-in-context-size

Conversation

@mkantautas

Copy link
Copy Markdown
Contributor

Problem

With useRenderInContext: true, width/height set the output size but do not resize the view: -[CALayer renderInContext:] draws the layer at its own size. A smaller size crops the capture to its top-left part; a larger size pads it with transparent pixels. The default drawViewHierarchyInRect: path resizes.

On a 200x100 view with four coloured quadrants (iOS simulator, example app):

captureRef(ref, { useRenderInContext: true, width: 100, height: 50 });  // only the top-left quadrant
captureRef(ref, { useRenderInContext: true, width: 400, height: 200 }); // view in the top-left quarter, rest transparent

Fix

When width/height differ from the natural capture size (the view's bounds, or the content size with snapshotContentContainer), scale the context from the natural size to the requested size before renderInContext:. Captures without width/height are unchanged.

Tests

RNViewShotRenderInContextTests (ViewShotExampleTests) calls captureRef:withOptions: with a stub UI manager and checks the image size and quadrant colours. The four resize cases (smaller, larger, snapshotContentContainer, transformed scroll view with snapshotContentContainer) fail on master and pass with the fix. The two natural-size cases (plain view, transformed scroll view) pass on both. The existing 14 tests pass.

From JS in the example app (iPhone 17 Pro simulator, iOS 26.3), useRenderInContext captures are now pixel-identical to the default strategy at natural size, 100x50 and 400x200. On master they match only at natural size.

Not run locally: Android, Windows, SwiftPM and Detox jobs (no change outside ios/RNViewShot.mm and the iOS test target).

#696 also edits this renderInContext branch (sublayer order); the two changes are independent.

-[CALayer renderInContext:] draws the layer at its own size, so with
useRenderInContext a width/height smaller than the view cropped the
capture and a larger one padded it with transparent pixels. Scale the
context to the requested size, as drawViewHierarchyInRect: does.

@gre gre left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks

@gre
gre merged commit e070ae4 into gre:master Oct 24, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants