software-mansion / software-mansion/react-native-screens

iOS: Large title jumps / offset appears during interrupted scroll

Open
#3,386 6 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

missing-info missing-repro platform:ios
Dominant language
TypeScript
Stars
3.7k
Forks
713
Avg merge
2d 23h
Merged PRs (30d)
71

Description

Description:
When using headerLargeTitle with Expo Router and react-native-screens, the large title collapses incorrectly when the scroll animation is interrupted — for example, if you start scrolling up, then release or drag again before the animation completes.

As a result, a visible offset (gap) appears between the header and the scroll content, and the list “jumps” slightly on small upward scrolls.
This makes the scroll interaction feel jittery and inconsistent.

The issue occurs consistently with both ScrollView and FlatList on iOS.


🔍 Environment
  • expo-router: ~6.0.14
  • react-native-screens: 4.18.0 (also reproducible on 4.16.0)
  • react-native: 0.81.5
  • expo: ~54.0.23 (prebuilt for iOS)
  • Platform: iOS (physical device + simulator)

🧩 Steps to Reproduce
  1. Create a new Expo project (npx create-expo-app largetitle)
  2. Add the following files:

app/_layout.tsx

import { Stack } from "expo-router";

export default function RootLayout() {
  return (
    <Stack
      screenOptions={{
        title: "Example",
        headerLargeTitle: true,
        headerShadowVisible: false,
        headerLargeTitleShadowVisible: false,
        headerLargeStyle: {
          backgroundColor: "yellow",
        },
      }}
    />
  );
}

app/index.tsx

import { ScrollView, Text, View } from "react-native";

export default function Index() {
  return (
    <ScrollView
      contentInsetAdjustmentBehavior="automatic"
      style={{ flex: 1, backgroundColor: "white" }}
    >
      {Array.from({ length: 100 }).map((_, i) => (
        <View
          key={i}
          style={{
            paddingVertical: 16,
            borderBottomWidth: 1,
            borderBottomColor: "#eee",
            alignItems: "center",
          }}
        >
          <Text style={{ fontSize: 18 }}>Text {i + 1}</Text>
        </View>
      ))}
    </ScrollView>
  );
}
  1. Run npx expo run:ios
  2. Scroll up slightly and interrupt the scroll (drag, pause, or change direction mid-gesture).
    → The large title collapses prematurely, creating a visible gap before snapping back.

🎥 Video

Attached below — shows how the large title collapses too early and creates a brief offset.

https://github.com/user-attachments/assets/562b326e-2fe1-45af-bd7c-37d0662677ff


✅ Expected behavior

The large title should collapse smoothly only after crossing the scroll threshold, without any jitter or visible offset when the scroll is interrupted.


❌ Actual behavior

Interrupting the scroll (by slightly dragging or holding) causes a layout jump and a temporary gap between the header and list content.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the reproduction in app/_layout.tsx and app/index.tsx, then run npx expo run:ios on the provided Expo setup. Reproduce an interrupted upward scroll with headerLargeTitle enabled on both ScrollView and FlatList. Done means the large title crosses its threshold smoothly without a jump or visible gap.

Written by the indexing model from the issue text.

Assessment

Tech stack
ios, react-native, typescript
Domain
mobile
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.