Skip to content

CupertinoSliverNavigationBar's collapse animation can get stuck in an infinite loop #164458

Closed

Description

@loic-sharma

Steps to reproduce

  1. Create a Cupertino app with a CupertinoSliverNavigationBar where the scrollable content extends past the viewport only if CupertinoSliverNavigationBar is expanded, but fits within the viewport if CupertinoSliverNavigationBar is collapsed.

  2. Scroll down to the bottom.

Expected results

The CupertinoSliverNavigationBar should collapse and stay collapsed.

Actual results

The CupertinoSliverNavigationBar loops between its collapsed and expanded mode forever.

Code sample

Code sample
import 'package:flutter/cupertino.dart';

void main() {
  runApp(
    CupertinoApp(
      home: CupertinoPageScaffold(
        child: CustomScrollView(
          slivers: [
            CupertinoSliverNavigationBar(
              largeTitle: Text('Hello World!'),
            ),
            SliverList.builder(
              // TODO: Edit the item count such that the list
              // extends past the viewport when the navigation
              // bar is expanded, but fits in the viewport when
              // the navigation bar is collapsed
              itemCount: 14,
              itemBuilder: (context, index) {
                return CupertinoListTile(
                  title: Text('Item $index'),
                );
              },
            ),
          ],
        ),
      ),
    ),
  );
}

Screenshots or Video

Screenshots / Video demonstration

Image

Logs

N/A

Flutter Doctor output

Doctor output
[✓] Flutter (Channel master, 3.29.0-1.0.pre.184, on Microsoft Windows [Version 10.0.26100.3194], locale en-US) [1,986ms]
    • Flutter version 3.29.0-1.0.pre.184 on channel master at C:\Code\f\flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 4d8585d936 (4 weeks ago), 2025-01-30 15:30:45 -0800
    • Engine revision 4d8585d936
    • Dart version 3.8.0 (build 3.8.0-24.0.dev)
    • DevTools version 2.42.0

[✓] Windows Version (11 Pro 64-bit, 24H2, 2009) [1,839ms]

[✓] Android toolchain - develop for Android devices (Android SDK version 32.1.0-rc1) [1,298ms]
    • Android SDK at C:\Users\sharm\AppData\Local\Android\sdk
    • Platform android-33, build-tools 32.1.0-rc1
    • Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java
      This is the JDK bundled with the latest Android Studio installation on this machine.
      To manually set the JDK path, use: `flutter config --jdk-dir="path/to/jdk"`.
    • Java version OpenJDK Runtime Environment (build 11.0.12+7-b1504.28-7817840)
    • All Android licenses accepted.

[✓] Chrome - develop for the web [73ms]
    • Chrome at C:\Program Files\Google\Chrome\Application\chrome.exe

[✓] Visual Studio - develop Windows apps (Visual Studio Community 2022 17.7.2) [72ms]
    • Visual Studio at C:\Program Files\Microsoft Visual Studio\2022\Community
    • Visual Studio Community 2022 version 17.7.34018.315
    • Windows 10 SDK version 10.0.22621.0

[✓] Android Studio (version 2021.2) [17ms]
    • Android Studio at C:\Program Files\Android\Android Studio
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • android-studio-dir = C:\Program Files\Android\Android Studio
    • Java version OpenJDK Runtime Environment (build 11.0.12+7-b1504.28-7817840)

[✓] VS Code (version 1.97.2) [15ms]
    • VS Code at C:\Users\sharm\AppData\Local\Programs\Microsoft VS Code
    • Flutter extension version 3.104.0

[✓] Connected device (3 available) [169ms]
    • Windows (desktop) • windows • windows-x64    • Microsoft Windows [Version 10.0.26100.3194]
    • Chrome (web)      • chrome  • web-javascript • Google Chrome 130.0.6723.70
    • Edge (web)        • edge    • web-javascript • Microsoft Edge 133.0.3065.92

[✓] Network resources [516ms]
    • All expected network resources are available.

• No issues found!

Activity

  1. changed the title [-]CupertinoSliverNavigationBar's expanded/collapsed animation can get stuck in an infinite loop[/-] [+]CupertinoSliverNavigationBar's collapse animation can get stuck in an infinite loop[/+] on Mar 2, 2025
  2. darshankawar commented on Mar 3, 2025

    @darshankawar
    Member

    Thanks for the report. I was able to replicate this specifically on web only using latest stable and master versions. The app gets stuck while running on desktop (macOS).

    stable : 3.29.0
    master : 3.30.0-1.0.pre.307
    
  3. added
    frameworkflutter/packages/flutter repository. See also f: labels.
    p: cupertino_uicupertino_ui package in flutter/packages
    platform-webWeb applications specifically
    has reproducible stepsThe issue has been confirmed reproducible and is ready to work on
    team-designOwned by Design Languages team
    f: scrollingViewports, list views, slivers, etc.
    and removed
    in triagePresently being triaged by the triage team
    on Mar 3, 2025
  4. self-assigned this
    on Mar 4, 2025
  5. victorsanni commented on Mar 5, 2025

    @victorsanni
    Contributor

    This issue seems to be from BouncingScrollPhysics on iOS/macOS. Even without the snap animation, BouncingScrollPhysics doesn't fully re-extend the scroll view when the nav bar is collapsed:

    Screen.Recording.2025-03-05.at.10.25.11.AM.mov

    If the nav bar is collapsed, then its contents all fit within the viewport, so bouncing scroll physics forces it to re-expand. But since it doesn't fully expand (and so the nav bar becomes partially scrolled), the snap animation triggers it to collapse, causing an infinite loop.

  6. added
    P2Important issues not at the top of the work list
    on Mar 12, 2025
  7. 3 remaining items

  8. techouse commented on Apr 28, 2025

    @techouse
    Contributor

    Interestingly, if the CupertinoSliverNavigationBar is in a CustomScrollview with ClampingScrollPhysics and gets stuck, no buttons on that screen seem to work until the animation is complete. That can be only fixed by adding additional padding to the main body.

  9. techouse commented on Jun 2, 2025

    @techouse
    Contributor

    @darshankawar this issue is still present in Flutter stable and master

    • 3.32.1 (stable)
    • 3.33.0-1.0.pre.313 (master).

    As I've mentioned above, the behaviour on iOS (and Web) is different to the one on Android. On iOS (and Web) the screen starts jumping up and down while on Android the buttons stop working.

    I've made a repo exhibiting the bug in detail https://github.com/techouse/CupertinoSliverNavigationBar_scroll_bug, essentially it boils down to:

    import 'package:flutter/cupertino.dart';
    import 'package:flutter/foundation.dart';
    import 'package:flutter/material.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Scroll Bug Demo',
          theme: ThemeData(
            colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
          ),
          home: const BugHomePage(),
        );
      }
    }
    
    class BugHomePage extends StatelessWidget {
      const BugHomePage({super.key});
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: CustomScrollView(
            slivers: [
              CupertinoSliverNavigationBar(largeTitle: Text('Hello Scroll Bug!')),
              SliverList.builder(
                // TODO: Edit the item count such that the list
                // extends past the viewport when the navigation
                // bar is expanded, but fits in the viewport when
                // the navigation bar is collapsed
                itemCount: switch (defaultTargetPlatform) {
                  // In my case an iPhone 16 Pro simulator needed 19 items to trigger the bug.
                  // FIXME: On iOS the we observe a jumpy screen and all buttons can be pressed.
                  TargetPlatform.iOS => 19,
                  // In my case an Android Pixel 9 Pro (API 36) emulator needed 21 items to trigger the bug.
                  // FIXME: On Android the screen is not jumpy, but the buttons are not pressable.
                  TargetPlatform.android => 21,
                  // In the case of web, simply make your browser window small enough to trigger the bug.
                  // FIXME: On web the we observe the same behavior as on iOS, the screen is jumpy and all buttons can be pressed.
                  _ => 21,
                },
                itemBuilder: (_, int index) => ListTile(
                  title: Text('Item $index'),
                  trailing: TextButton(
                    onPressed: () {
                      debugPrint('Button $index has been pressed!');
                      ScaffoldMessenger.of(context).showSnackBar(
                        SnackBar(
                          behavior: SnackBarBehavior.floating,
                          shape: RoundedRectangleBorder(
                            borderRadius: BorderRadius.circular(24),
                          ),
                          content: Text('Button $index pressed!'),
                        ),
                      );
                    },
                    child: Text('Buton $index'),
                  ),
                  // TODO: You might want to either enable or disable the density
                  // to see the difference in behavior
                  dense: true,
                  // TODO: You might want to either enable or disable the visual
                  // density to see the difference in behavior
                  visualDensity: VisualDensity.compact,
                ),
              ),
            ],
          ),
        );
      }
    }
  10. techouse commented on Jun 7, 2025

    @techouse
    Contributor

    The bug is still present in:

    • 3.32.2 (stable)
    • 3.33.0-1.0.pre.416 (master)
  11. techouse commented on Jun 7, 2025

    @techouse
    Contributor

    @victorsanni I’ve finally had some more time to look into this and have identified that the bug starts appearing in 83a0b85, the PR is #156381. I’ll do some more digging and debugging and report my findings.

  12. victorsanni commented on Jun 7, 2025

    @victorsanni
    Contributor

    I’ve finally had some more time to look into this and have identified that the bug starts appearing in 83a0b85, the PR is #156381. I’ll do some more digging and debugging and report my findings.

    Yes, but the underlying issue isn't from the snap animation PR:

    Even without the snap animation, BouncingScrollPhysics doesn't fully re-extend the scroll view when the nav bar is collapsed.

  13. techouse commented on Jun 8, 2025

    @techouse
    Contributor

    Even without the snap animation, BouncingScrollPhysics doesn't fully re-extend the scroll view when the nav bar is collapsed.

    @victorsanni but I don't think that BouncingScrollPhysics is to blame. When CustomScrollView is configured to use BouncingScrollPhysics (iOS default) the screen becomes jumpy, however, if I configure my CustomScrollView to use ClampingScrollPhysics (Android default) all of the buttons stop working.

    Scaffold(
      body: CustomScrollView(
        physics: const ClampingScrollPhysics(), // <-- 
        slivers: [
          CupertinoSliverNavigationBar(largeTitle: Text('Hello Scroll Bug!')),
          SliverList.builder(
            children: [
              // ... buttons
            ],
          )
        ],
      ),
    );

    For now, I have only tried removing the animation on line

    and the bug is gone, however, that's a rather crude approach.

    EDIT: I think I've found a solution by modifying the triggering condition from

    to

    if (target != null && target <= position.maxScrollExtent) {
      position.animateTo(
        target,
        // Eyeballed on an iPhone 16 simulator running iOS 18.
        duration: const Duration(milliseconds: 300),
        curve: Curves.fastEaseInToSlowEaseOut,
      );
    }

    EDIT2: I made a PR with the change #170210

  14. added
    r: fixedIssue is closed as already fixed in a newer version
    on Jul 2, 2025
  15. github-actions commented on Jul 16, 2025

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  16. locked as resolved and limited conversation to collaborators on Jul 16, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work listf: scrollingViewports, list views, slivers, etc.found in release: 3.29Found to occur in 3.29found in release: 3.30Found to occur in 3.30frameworkflutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onp: cupertino_uicupertino_ui package in flutter/packagesplatform-webWeb applications specificallyr: fixedIssue is closed as already fixed in a newer versionteam-designOwned by Design Languages teamtriaged-designTriaged by Design Languages team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions