Skip to content

Conversation

@johankasperi
Copy link
Contributor

@johankasperi johankasperi commented Oct 29, 2025

Description

When using RCTImageLoader for images in headerRightItems/headerLeftItems the asynchronous loadImageWithURLRequest produces som layout bugs as shown under "Screenshots". These are:

  1. When setting title and image the title is briefly visible before the image is set.
  2. When setting only image the bar button item is briefly shown as a very wide item without any content.

Changes

  1. If the image is a ImageRequireSource load the image with [RCTConvert UIImage]. I know its deprecated but thats the only synchronous image loader that I know of.
  2. If the image is a ImageURISource set the bar button title in the completion block of loadImageWithURLRequest
  3. Updates BarButtonItems example to latest types/api from react-navigation/native-stack.

Screenshots / GIFs

Before

Title briefly shown

Simulator.Screen.Recording.-.iPhone.17.Pro.-.2025-10-29.at.21.51.42.mov

Wide bar button item while loadImageWithURLRequest completes

Simulator.Screen.Recording.-.iPhone.17.Pro.-.2025-10-29.at.22.19.46.mov

After

Simulator.Screen.Recording.-.iPhone.17.Pro.-.2025-10-29.at.22.20.18.mov

Test code and steps to reproduce

Use any of the examples with required images in BarButtonItems

Checklist

@kkafar kkafar self-requested a review October 31, 2025 11:23
Copy link
Member

@kkafar kkafar left a comment

Choose a reason for hiding this comment

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

Yeah, we have this ugly effect now.

The situation here is a bit more complex.

First: in release mode, the code using RCTImageLoader will work just fine if we remove dispatch_async in completion block -> because this is the source of the delay.

In debug mode, when the assets are not loaded from application bundle (not talking about JS bundle here, rather NSBundle), but are downloaded from packager, RCTImageLoader does this asynchronously, indeed.

Since RCTConvert for image related conversions got deprecated, I'd like to limit its usage only for debug mode, where we can not load images synchronously in any other way. We could do this manually, but I'd like to avoid that option even more.

I'll start conversation with React Native team about giving us support for synchronous loading, since this will be rather a regression if the RCTConvert UIImage gets removed and we don't have any other sync API.

@kkafar
Copy link
Member

kkafar commented Oct 31, 2025

Also disadvantage of using RCTConvert is that we don't have any image caching.

Copy link
Member

@kkafar kkafar left a comment

Choose a reason for hiding this comment

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

I'm drafting a refactor & noticed this. Just a question.

return self;
}

self.title = dict[@"title"];
Copy link
Member

Choose a reason for hiding this comment

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

Why did you resign from setting title here and postponed it for later? Was there a particular reason here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I didn't want to set the title before remote images had been downloaded

Copy link
Contributor Author

Choose a reason for hiding this comment

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

But shouldn't be needed anymore since from what I understand also remote images will be loaded synchronously in production mode?

Copy link
Member

Choose a reason for hiding this comment

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

No, only assets stored on the device will be loaded synchronously. If you need to download header button images from some remote source during runtime (is this a valid use case?) it'll be done asynchronously. Packager (metro) assets are treated like device-local assets, so they're exception to that rule & will be loaded synchronously.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah I don't think its a valid use case. Just something to be aware of that the title will be shown until the image is loaded then if the download is done asynchronously.

Copy link
Member

@kkafar kkafar left a comment

Choose a reason for hiding this comment

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

I've refactored the code a bit. I'll be willing to land this if you confirm that also works for you.

@johankasperi
Copy link
Contributor Author

I've refactored the code a bit. I'll be willing to land this if you confirm that also works for you.

Thank you! And thanks for explaining how RCTImageLoader works in production/debug mode. Your refactor is working in my testing so feel free to merge

@johankasperi
Copy link
Contributor Author

I've refactored the code a bit. I'll be willing to land this if you confirm that also works for you.

Thank you! And thanks for explaining how RCTImageLoader works in production/debug mode. Your refactor is working in my testing so feel free to merge

One thing to be aware of now though is that you cant load images of type ImageURISource in debug mode. It works in production mode. But using ImageURISource for icons in the header should not be a common use case

@johankasperi johankasperi force-pushed the header-items-icon-title-refactor branch from 6ee8302 to 5db502d Compare November 4, 2025 12:58
@johankasperi
Copy link
Contributor Author

@kkafar I refactored now so we got the changes from #3347 Feel free to have a look at it. Thanks!

@johankasperi johankasperi requested a review from kkafar November 4, 2025 12:59
Copy link
Member

@kkafar kkafar left a comment

Choose a reason for hiding this comment

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

Thanks for catching this.

I'll land this PR once CI passes.

Regarding ImageURISource - thanks for reporting this. We might wanna handle this separately.

@kkafar kkafar changed the title fix: use synchronous RCTConvert for asset images fix(iOS): load header items icons synchronously when feasible Nov 4, 2025
@kkafar kkafar merged commit 4837a83 into software-mansion:main Nov 4, 2025
6 checks passed
kligarski added a commit that referenced this pull request Nov 5, 2025
## Description

It seems like in
#3355,
`react-navigation` submodule has been changed from `7.x` branch
(react-navigation/react-navigation@3d1e4ef)
to older commit from `main` branch
(react-navigation/react-navigation@782b6d4).
We probably want to keep in sync with `7.x` branch for now.

This PR updates `react-navigation` submodule to latest commit from `7.x`
branch.

## Changes

- update `react-navigation` submodule to
react-navigation/react-navigation@359df7d

## Test code and steps to reproduce

Run example app.

## Checklist

- [x] Ensured that CI passes
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