Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

App freeze on transition in iOS when Get.snackbar is open and swipe right gesture executed #773

Closed
pa2codes opened this issue Nov 6, 2020 · 20 comments

Comments

@pa2codes
Copy link

pa2codes commented Nov 6, 2020

Describe the bug
When I use Get.toNamed() to new screen, then open snackbar on onTab() of a button, and while snackbar is showing using iOS native swipe right function the screen freezes while in transition.

**Reproduction code
example:

void main() => runApp(MaterialApp(home: Home()));

class Home extends StatefulWidget {

  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> with SingleTickerProviderStateMixin, AutomaticKeepAliveClientMixin {

//init etc.
//I use DefaultTabController in this class

  @override
  bool get wantKeepAlive => true;

  @override
  Widget build(context){
   super.build(context);
   return ...
      Scaffold(
      appBar: AppBar(title: Text("Start page")),
      body: Center(
        child: Obx(() => Text("Click button to go to next page")),
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: () => Get.toNamed('/my_new_page'),
      ));
 }
}

class MyNewPage extends StatelessWidget {

  @override
  Widget build(BuildContext context) {

    return BaseResponsiveWidget(builder: (context, sizingInformation) {
      return Scaffold(
          resizeToAvoidBottomInset: false,
          body: Container(child: Text("MyNewPage")),
          floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: () => Get.Snackbar("Title", "Body"),
      ));
      );
   })

To Reproduce
Steps to reproduce the behavior:

  1. Widget with button -> onTab() => Get.toNamed('/new_widget')
  2. In new Widget have button with -> onTab() => Get.snackbar()
  3. swipe rigth on iOS device to go to previous widget
  4. App freezes

Expected behavior
Get.Snackbar should be closed before transition

Screenshots
grafik

Flutter Version:
1.22.0 • channel stable

Getx Version:
get: '^3.15.0'

Describe on which device you found the bug:
all iOS devices

Minimal reproduce code
s.o.

@Asored-D
Copy link

I can confirm this issue. I have it too for all my iOS devices. 😊

@jerem17
Copy link

jerem17 commented Nov 24, 2020

Yes I have it too ...

@eduardoflorence
Copy link
Collaborator

Please, can you check the Flutter's snackbar also have the same problem?

https://flutter.dev/docs/cookbook/design/snackbars

@eduardoflorence
Copy link
Collaborator

Try this:

void main() {
  runApp(GetMaterialApp(
    home: Home(),
    popGesture: true,
    defaultTransition: Transition.cupertino,
  ));
}

Repository owner deleted a comment from sooxt98 Dec 9, 2020
@pa2codes
Copy link
Author

@eduardoflorence Thanks for your reply! I tried your solution, but the freeze still exists.

@eduardoflorence
Copy link
Collaborator

@jonataslaw, I put an example below that is easier to reproduce. If you comment on the Get.scnackbar line and uncomment Scaffold.of(context).showSnackBar(snackBar) line you can see that the problem doesn’t happen, that is, the flutter’s SnackBar doesn’t cause a freeze if we swipe to return to the previous screen.

import 'package:flutter/material.dart';
import 'package:get/get.dart';

void main() {
  runApp(GetMaterialApp(
    initialRoute: '/home',
    defaultTransition: Transition.cupertino,
    popGesture: true,
    getPages: [
      GetPage(name: '/home', page: () => Home()),
      GetPage(name: '/my_new_page', page: () => MyNewPage()),
    ],
  ));
}

class Home extends StatelessWidget {
  @override
  Widget build(context) {
    return Scaffold(
      appBar: AppBar(title: Text("Start page")),
      body: Center(
        child: RaisedButton(
          child: Text("Click button to go to next page"),
          onPressed: () => Get.toNamed('/my_new_page'),
        ),
      ),
    );
  }
}

class MyNewPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('New Page'),
      ),
      body: SnackBarPage(),
    );
  }
}

class SnackBarPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: ElevatedButton(
        onPressed: () {
          final snackBar = SnackBar(
            content: Text('Yay! A SnackBar!'),
          );

          // Not freeze
          // Scaffold.of(context).showSnackBar(snackBar);

          // Freeze
          Get.snackbar('title', 'message');
        },
        child: Text('Show SnackBar'),
      ),
    );
  }
}

@jonataslaw
Copy link
Owner

@jonataslaw, I put an example below that is easier to reproduce. If you comment on the Get.scnackbar line and uncomment Scaffold.of(context).showSnackBar(snackBar) line you can see that the problem doesn’t happen, that is, the flutter’s SnackBar doesn’t cause a freeze if we swipe to return to the previous screen.

import 'package:flutter/material.dart';
import 'package:get/get.dart';

void main() {
  runApp(GetMaterialApp(
    initialRoute: '/home',
    defaultTransition: Transition.cupertino,
    popGesture: true,
    getPages: [
      GetPage(name: '/home', page: () => Home()),
      GetPage(name: '/my_new_page', page: () => MyNewPage()),
    ],
  ));
}

class Home extends StatelessWidget {
  @override
  Widget build(context) {
    return Scaffold(
      appBar: AppBar(title: Text("Start page")),
      body: Center(
        child: RaisedButton(
          child: Text("Click button to go to next page"),
          onPressed: () => Get.toNamed('/my_new_page'),
        ),
      ),
    );
  }
}

class MyNewPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('New Page'),
      ),
      body: SnackBarPage(),
    );
  }
}

class SnackBarPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: ElevatedButton(
        onPressed: () {
          final snackBar = SnackBar(
            content: Text('Yay! A SnackBar!'),
          );

          // Not freeze
          // Scaffold.of(context).showSnackBar(snackBar);

          // Freeze
          Get.snackbar('title', 'message');
        },
        child: Text('Show SnackBar'),
      ),
    );
  }
}

Every child of route since version 1.17 needs to be involved with an iOS motion detector.
I added to GetPageRoute, but I think it will be necessary to add to GetBottomSheetRoute, SnackRoute and GetDialogRoute.

This will require some code refactor, but will likely be fixed in the next update.

Thanks for the reproduction code, this will make my job a lot easier.

@ktw1318
Copy link

ktw1318 commented Feb 11, 2021

me too. is there way to fix it?

@ktw1318
Copy link

ktw1318 commented Feb 14, 2021

Get 3.25.4 Version still same issue . When it does woking ?

@DohanKim
Copy link

any progress here?

@LOCKEDFILE
Copy link

LOCKEDFILE commented May 21, 2021

I suggest a solution.

The solution is not perfect. but It's working for me.

First Step

  • Getx contains parameters snackbarStatus
Get.snackbar(
  title,
  content,
  snackbarStatus: (_) {
    if (_ == SnackbarStatus.CLOSED || _ == SnackbarStatus.CLOSING) {
      WidgetsBinding.instance.addPostFrameCallback((_) {
        final dismissController = Get.find<DismissNavigationController>();
        if (dismissController.isDismiss) Get.back();
        dismissController.setDone();
      });
    }
  },

Second Step

  • Make DismissNavigationController extends GetxController
  • or Just static var
class DismissNavigationController extends GetxController {
  bool _dismiss = false;
  bool get isDismiss => _dismiss;
  setDismiss() => _dismiss = true;
  setDone() => _dismiss = false;
}

Third Step

  • Make NavigatorObserver
class DismissNavigationObserver extends NavigatorObserver {
  @override
  void didStartUserGesture(Route route, Route previousRoute) {
    Get.find<DismissNavigationController>().setDismiss();
    super.didStartUserGesture(route, previousRoute);
  }
  @override
  void didPush(Route<dynamic> route, Route<dynamic> previousRoute) {
    Get.find<DismissNavigationController>().setDone();
  }
}
  • Add Observer
GetMaterialApp(
  navigatorObservers: [
    DismissNavigationObserver(),
  ],
  ....

Good Luck.

@harishkthedeveloper
Copy link

I am also facing the same issue in flutter, when snackbar is open if i swipe back the ui getting freeze

@harishkthedeveloper
Copy link

Any proper fix ? advanced thanks

@harishkthedeveloper
Copy link

harishkthedeveloper commented Sep 20, 2021

@LOCKEDFILE i tried your solution but its not working for me

@rajeevjaiswal
Copy link

Any fix for this issue?

@chirastefan
Copy link

chirastefan commented Oct 13, 2021

I am also facing a related issue, when the snackbar is opened the cursor lags, IOS simulator, iPhone 13, after it disappears it works fine.

@vsly-ru
Copy link

vsly-ru commented Oct 22, 2021

The issue is almost 1 year old.
Maybe just automatically dismiss the snack when the gesture starts?

@azeek
Copy link

azeek commented Nov 30, 2021

Is this fixed in GetX 4.5.1 version?

@jonataslaw
Copy link
Owner

Fixed on latest version

@Natan-hub
Copy link

I have this same problem using the another_flushbar package that when you swipe and the screen gets stuck and it was said to have been fixed, using the flutter documentation I saw that it doesn't crash but when swiping the snack bar ends up going to the previous screen too and it does not close. Is there no way to close it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests