Skip to content

fix: 修正图片在iphone8下高度展示不对, scroll-view如果是设置flex的话展示异常 - #2510

Open
wangxiaokou wants to merge 6 commits into
masterfrom
fix-image-scroll-view-bug
Open

fix: 修正图片在iphone8下高度展示不对, scroll-view如果是设置flex的话展示异常#2510
wangxiaokou wants to merge 6 commits into
masterfrom
fix-image-scroll-view-bug

Conversation

@wangxiaokou

Copy link
Copy Markdown
Collaborator
  1. 修正在iphone8下RNImage.getSize获取不到宽高的问题
  2. 修正在web下,如果给scroll-view设置display:flex 无法滚动的问题

const width = (source && source.width) || nativeEvent.width || 0
const height = (source && source.height) || nativeEvent.height || 0
// 布局模式下,若 getImageSize 没拿到尺寸(iPhone 8 返回 0,ratio 仍为 0),用真实尺寸兜底同步 view
if (isLayoutMode && width && height && !state.current.ratio) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

这里只是为了触发一下onLoad事件,为啥要加这堆逻辑?这堆逻辑在单独的getImageSize里有

@hiyuki hiyuki left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

有以下几个问题需要处理:

  1. [P1] 动态切换 src 时可能永久沿用旧图片比例。 新增兜底受 !state.current.ratio 限制;第一张图片已经建立 ratio 后,如果切换到第二张图片且 RNImage.getSize 失败,即使第二张图的 onLoad 返回了正确宽高,也会跳过尺寸更新,widthFixheightFix 和裁剪模式会继续使用上一张图的比例。建议在 src 变化时重置对应尺寸状态,或者允许当前图片的 onLoad 尺寸覆盖旧状态,同时注意避免旧图片异步事件覆盖新图片状态。

@hiyuki

hiyuki commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

该问题如果在image存在,理论上在view的background-image中也会存在

@hiyuki

hiyuki commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

当前实现使用onLoad作为getImageSize失败的兜底,链路过长,可以改成并行获取,谁先获取到使用谁,未就绪时使用opacity: 0,而不是不挂载;

对于view+backgroundImage也采用相同方式修复改造

测试一下并行竞速情况下onload和getImageSize一般谁返回快

@hiyuki

hiyuki commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

补充一个实现建议:当前方案以 onLoad 作为 getImageSize 失败后的串行兜底,链路是“getImageSize 失败 → 渲染 Image → 等待 onLoad → 回填尺寸”,状态分支较多。可以考虑改为并行获取:布局模式下立即调用 getImageSize,同时渲染 Image(尺寸未就绪前通过 opacity: 0 隐藏),由 getImageSizeonLoad 竞争提供尺寸,首个有效结果生效。

建议注意以下实现边界:

  1. 抽取统一的 resolveImageSize(width, height, generation),集中更新 imageWidthimageHeightratiosetViewSize,避免两条路径重复并逐渐分叉。
  2. 每次 src 变化时创建新的 generation/token 并重置尺寸就绪状态;迟到的旧图片回调必须校验 generation,避免覆盖新图片状态。仅使用一个 sizeResolvedRef 不足以隔离旧 src
  3. 同一 generation 内只接受第一个有效尺寸结果,忽略另一条路径的迟到结果。
  4. bindload 与尺寸竞速分离:getImageSize 成功只代表获取到尺寸,并不代表图片加载完成;即使它先获胜,真实 onLoad 到达时仍需正常触发用户的 bindload
  5. onLoad 同时兼容 RN Image 的 nativeEvent.source.width/height 和 FastImage 的 nativeEvent.width/height

整体链路可以收敛为:

src 变化
├─ getImageSize(src)
└─ 立即渲染隐藏的 Image
   └─ onLoad 获取真实尺寸

任一路径先返回有效宽高
└─ resolveImageSize
   ├─ 校验 generation
   ├─ 同一 generation 仅提交一次
   └─ 更新 ratio 和 view size

这样既能避免依赖 getImageSize 是否及时触发失败回调,也能顺带解决动态切换 src 时旧比例/旧异步结果残留的问题。代价是 Image 与 getImageSize 会同时启动,但通常可以利用底层缓存,整体状态机也更清晰。

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