Skip to content

feat(iOS) - url function support in backgroundImage - #58248

Open
intergalacticspacehighway wants to merge 9 commits into
react:mainfrom
intergalacticspacehighway:background-image-url-ios
Open

intergalacticspacehighway wants to merge 9 commits into
react:mainfrom
intergalacticspacehighway:background-image-url-ios

Conversation

@intergalacticspacehighway

@intergalacticspacehighway intergalacticspacehighway commented Aug 30, 2026 •

Copy link
Copy Markdown
Collaborator

Summary:

Note

iOS CI fails until #58246 (JS/parser) is merged. This PR uses the URLBackgroundImage type that #58246 adds.

Recreated from #54996, which was auto-closed when my fork was deleted. GitHub does not allow reopening a PR whose head repository is gone. Rebased onto current main.

How:

  • RCTViewComponentView loads the url() images when it receives props, through the same ImageManager pipeline as the Image component.
  • RCTBackgroundImageURLLoader keeps one request per unique url. It cancels a request when its url is removed, or when the view is recycled or deallocated.
  • RCTSurfacePresenter puts one shared ImageManager in the context container, unless the app already added one. <Image> now uses this ImageManager too.
  • RCTMountingManager passes the ImageManager to RCTComponentViewRegistry, which gives it to each new RCTViewComponentView.

Changelog:

[IOS] [ADDED] - url support with backgroundImage

Test Plan:

Screenshots

Each url() example in RN Tester, opened by deep link, on the iOS simulator, with all three PRs merged:

URL Image URL Image from local file Local file at its natural size (@3x asset, 33x33)

Follow-ups

  • Decode images at the size they are drawn, instead of full size.
  • cover and contain support for backgroundSize.

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Aug 30, 2026
@intergalacticspacehighway
intergalacticspacehighway marked this pull request as draft August 30, 2026 13:05
@intergalacticspacehighway
intergalacticspacehighway force-pushed the background-image-url-ios branch 3 times, most recently from d123490 to f4d9407 Compare August 31, 2026 13:36
Move url() loading out of ViewShadowNode, ViewState, and
ViewComponentDescriptor. RCTViewComponentView now starts the requests
in finalizeUpdates through RCTBackgroundImageURLLoader, using the
ImageManager that RCTMountingManager passes to the component view
registry. No shared C++ or build file changes remain.
RCTSurfacePresenter puts one ImageManager into the context container, so
ImageComponentDescriptor and RCTMountingManager use the same instance and
RCTImageLoader gets requests from one serial queue only.

Background images that are not UIImageOrientationUp are drawn once into an
upright image, because the layer draws the CGImage, which ignores
imageOrientation.
An auto dimension in backgroundSize now uses the image's aspect ratio,
including after round repeat, as CSS does. Gradients have no ratio and
keep their current behavior.

Rename -[RCTViewComponentView setImageManager:] to
setBackgroundImageManager:, so it cannot collide with a subclass
property, and redraw rotated images off the main queue.
@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Visual regression

No visual differences at ce03714ce55f.

ios: no capture

When the tile is more than twice the size of the box, round() gives 0
and the tile kept its size. CSS requires at least one tile, so the tile
now shrinks to fit the box. This also applies to gradients.
… iOS

A layer draws the CGImage, which ignores imageOrientation. Instead of
redrawing the whole image into a new bitmap, show the CGImage in a
sublayer and rotate or mirror it with a transform. This removes the
second bitmap and the background-queue redraw.
…isting ImageManager

- The exported header now includes <React/Graphics.h> and
  <React/RendererCore.h>, so it builds under RN_STRICT_API like the
  other React/Fabric headers.
- RCTSurfacePresenter creates the shared ImageManager only when the
  context container does not have one yet. insert() keeps an existing
  value, so the extra ImageManager was created and thrown away.
RCTBackgroundImageUtilsTests checks:
- an auto size keeps the aspect ratio of a url image, but not of a
  gradient
- background-repeat: round uses at least one tile
- createURLImageLayerWithImage:size: draws all 8 EXIF orientations
  with the same pixels as UIImage
@intergalacticspacehighway
intergalacticspacehighway marked this pull request as ready for review October 29, 2026 14:35
@facebook-github-tools facebook-github-tools Bot added the Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. label Oct 29, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant