Skip to content

GiftedChat message list renders dimmed (~0.5 opacity) on iOS NativeTabs screen #191

@Kelbie

Description

@Kelbie

Summary

On the AI tab, the react-native-gifted-chat message list renders with what appears to be ~0.5 opacity — bubbles, the date chip, and other GiftedChat-rendered content all look washed out / dimmed. The same GiftedChat usage on other screens (e.g. modals) renders fully opaque, so this is specific to the NativeTabs hosting context.

Hardcoding bright/saturated colors directly into bubble styles does not fix it: the underlying solid background still composites toward the screen background. The plain (non-GiftedChat) red background of the screen stays fully saturated — only the GiftedChat scroll-view content is dimmed. So this is not a bubble-styling bug in app code.

Repro

  • Open the AI tab (app/(drawer)/(tabs)/ai/...) on iOS.
  • Render GiftedChat with isInverted left at its default (true).
  • Observe: messages, date chip, and other list-rendered content appear dimmed/faded.
  • Workaround: passing isInverted={false} to GiftedChat fully removes the dim. This is not an acceptable fix because it breaks bottom-anchored chat UX, scroll-to-bottom behavior, keyboard handling, and message ordering assumptions.

Additional observed behavior:

  • When scrolling past the end of the content (overscroll), the dim animates away across the entire view, not just at the edge. This strongly suggests an iOS scroll-edge effect / material layer that is keyed off the inverted scroll view's content offset.

What we have ruled out

  • Not bubble color / opacity in app code — verified by hardcoding bright backgrounds in the shared ChatScreen renderers.
  • Not the tab bar disableTransparentOnScrollEdge setting — that controls the tab bar's own transparency, not the scroll content.
  • Not solved by setting disableAutomaticContentInsets + unstable_nativeProps.scrollEdgeEffects.bottom = 'hidden' on the AI <NativeTabs.Trigger>.
  • Not solved by removing GiftedChat's custom CellRendererComponent when isDayAnimationEnabled is false (patched and tested).
  • Not solved by inserting a zero-size collapsable={false} sentinel before GiftedChat's AnimatedFlatList to prevent react-native-screens from discovering the inverted scroll view as the first nested scroll view.
  • Not solved by swapping GiftedChat's react-native-gesture-handler FlatList wrapper for React Native's FlatList directly (removes one scroll wrapper from the inverted transform path).

Current working theory

The bug is a composition of three things:

  1. GiftedChat uses an inverted FlatList by default (isInverted = true). React Native implements inverted via a scale transform on the scroll view (see VirtualizedList docs).
  2. Expo / react-native-screens NativeTabs auto-discovers the first nested scroll view on iOS and attaches iOS 26 scroll-edge effects (blur/fade material) to it. See scrollEdgeEffects in react-native-screens.
  3. iOS 26's scroll-edge fade applies in the scroll view's transformed coordinate space. When the scroll view is flipped (GiftedChat inversion), the fade material is composited over the entire visible content rather than only at the edge, producing a uniform dim.

This matches the symptom that overscrolling animates the dim away across the whole view — the fade is driven by content offset relative to the (flipped) edge.

There is a closely matching report on the Apple Developer Forums describing iOS 26 navigation-bar fade misbehaving with inverted ScrollViews. The behavior described there (fade applied in transformed coordinates, covering the screen) is consistent with what we see here.

Why this matters

GiftedChat is the standard React Native chat UI and isInverted is the recommended path for bottom-anchored chat. With NativeTabs becoming the default tab implementation on iOS, any app that hosts GiftedChat inside a NativeTabs screen on iOS 26 will hit this. The only known workaround today (isInverted={false}) gives up GiftedChat's core UX guarantees.

Asks

  • Confirm whether others can reproduce on iOS 26 + Expo NativeTabs + GiftedChat (inverted).
  • Guidance on whether the right fix lives in:
    • react-native-gifted-chat (e.g. opt out of inversion in favor of a non-transform-based bottom anchor),
    • react-native-screens / Expo NativeTabs (do not auto-attach scroll-edge effects to inverted scroll views, or expose a per-screen opt-out that actually disables the material), or
    • app-level configuration we have missed.

Environment

  • iOS 26
  • Expo SDK with NativeTabs (expo-router / react-native-screens NativeTabs)
  • react-native-gifted-chat@3.3.2
  • Reanimated v4
  • react-native-gesture-handler

Related files in this repo

  • app/(drawer)/(tabs)/_layout.tsx — NativeTabs configuration, disableTransparentOnScrollEdge, and the probe for disableAutomaticContentInsets / scrollEdgeEffects.
  • app/(drawer)/(tabs)/ai/_layout.tsx — AI tab stack.
  • features/ai/screens/AiChatScreen.tsx — AI chat screen entry point and hardcoded repro site.
  • shared/ui/composed/chat/ChatScreen.tsx — shared chat renderer around GiftedChat.
  • patches/react-native-gifted-chat+3.3.2.patch — current investigatory patch (FlatList wrapper swap).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions