简体   繁体   English

Flutter:在 iOS 和 Android 中禁用滑动以返回导航

[英]Flutter: Disable Swipe to Navigate Back in iOS and Android

I'm new to flutter development, and find it a bit frustrating in iOS when you have a navigation drawer and when you swipe to open it, it'll perform a Navigation.of(context).pop() .我是 Flutter 开发的新手,当你有一个导航抽屉并且当你滑动打开它时,它会在 iOS 中发现它有点令人沮丧,它会执行Navigation.of(context).pop() I would like to disable this "swipe to pop" behavior in iOS.我想在 iOS 中禁用这种“滑动弹出”行为。 I have been perusing the documentation, but without much luck.我一直在仔细阅读文档,但运气不佳。

I do see something referred to as aWillPopScope which seems to do the trick ( github issue for it here ), but I'm not 100% sure if this is the "correct" way to do it (it seems too complicated... it should be easier... like a setting on the root app).我确实看到了一些被称为WillPopScope东西,它似乎可以解决问题(此处为 github 问题),但我不能 100% 确定这是否是“正确”的方法(似乎太复杂了...它应该更容易......就像根应用程序上的设置一样)。

WillPopScope is the correct way to do this. WillPopScope执行此操作的正确方法。

(it seems too complicated... it should be easier... like a setting on the root app). (这似乎太复杂了......它应该更容易......就像根应用程序上的设置一样)。

It is not complicated.这并不复杂。 It's a one liner :这是一个单班轮:

WillPopScope(
  onWillPop: () async => false,
  child: <children here>
)

A configuration file would make things more complicated as it's harder to read and maintain.配置文件会使事情变得更加复杂,因为它更难阅读和维护。

And remember that in flutter everything is a widget not just half of them.请记住,在 flutter 中,一切都是小部件,而不仅仅是其中的一半。 Authentification, configurations, everything.认证,配置,应有尽有。

I have one additional point here.我还有一点要补充。 I was just solving this problem, but I also needed my user to be able to go back by pressing the "native" back button on the AppBar (did not want to reimplement AppBar just because of this), and I found this niche little flag: userGestureInProgress on the Navigator object, so what I use (and presume is the preferred way) is:我只是在解决这个问题,但我也需要我的用户能够通过按下 AppBar 上的“原生”后退按钮返回(不想因为这个而重新实现 AppBar),我发现了这个利基小标志:在 Navigator 对象上的userGestureInProgress ,所以我使用的(并且假定是首选方式)是:

onWillPop: () async {
    if (Navigator.of(context).userGestureInProgress)
      return false;
    else
      return true;
  },

MaterialPageRoute has a parameter called fullscreenDialog which is set to false by default. MaterialPageRoute有一个名为fullscreenDialog的参数,默认设置为 false。 When true your page animates a bit differently and swipe to go back on iOS will be disabled.当 true 时,您的页面动画会有所不同,并且在 iOS 上滑动返回将被禁用。

Example usage:用法示例:

 Navigator.of(context).push(
        MaterialPageRoute(builder: (_) => HomePage(), fullscreenDialog: true));

See some discussion here: https://github.com/flutter/flutter/issues/14203请参阅此处的一些讨论: https : //github.com/flutter/flutter/issues/14203

You can try this in your Widget build:您可以在您的 Widget 版本中尝试此操作:

@override
  Widget build(BuildContext context) {
    return WillPopScope(//forbidden swipe in iOS(my ThemeData(platform: TargetPlatform.iOS,)
      onWillPop: ()async {
        if (Navigator.of(context).userGestureInProgress)
          return false;
        else
          return true;
      },
      child: <your child>,
    );
  }

Alright, so as @Darky said WillPopScope is a perfectly acceptable answer, however, if you want to disable it across the board you can actually do the following.好吧,正如@Darky 所说WillPopScope是一个完全可以接受的答案,但是,如果您想全面禁用它,您实际上可以执行以下操作。

Open your project in xcode, find AppDelegate.swift and add the following:在 xcode 中打开您的项目,找到AppDelegate.swift并添加以下内容:

let controller: FlutterViewController
    = window?.rootViewController as! FlutterViewController;
controller.navigationController?
    .interactivePopGestureRecognizer?.isEnabled = false;

I had a similar problem where I wanted to block the swipe to return back in navigation (default pop function).我有一个类似的问题,我想阻止滑动以返回导航(默认弹出功能)。 This code helped fix the problem.此代码有助于解决问题。

@override
Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () async => false,
      child: Scaffold(
        body: Center(
          child: Text('Example'),
        ),
      ),
    );
  }

This code now blocks the back navigation for iOS & Android (default back button) and that's exactly what I was looking for.此代码现在阻止了 iOS 和 Android(默认后退按钮)的后退导航,这正是我正在寻找的。 Hope this helps.希望这会有所帮助。

I am not quite sure what you want to achieve, but most of the time when people want to get rid of the back functionality, because they don't wanna enable the user to control the auth mechanism.我不太确定你想要实现什么,但大多数时候人们想要摆脱后台功能,因为他们不想让用户控制身份验证机制。 For example after the users log in, you don't want them to navigate to the Login page by just press on the back button(or swipe back in iOS).例如,在用户登录后,您不希望他们通过按后退按钮(或在 iOS 中向后滑动)导航到登录页面。 A potential solution is, using pushNamedAndRemoveUntil .一个潜在的解决方案是使用pushNamedAndRemoveUntil

Future<T> pushNamedAndRemoveUntil<T extends Object>(BuildContext context, String newRouteName, RoutePredicate predicate)

Push the route with the given name onto the navigator that most tightly encloses the given context, and then remove all the previous routes until the predicate returns true.将具有给定名称的路由推送到最紧密包围给定上下文的导航器上,然后删除所有先前的路由,直到predicate返回 true。

Example code: pushNamedAndRemoveUntil(context, '/home', ModalRoute.withName('/home'));示例代码: pushNamedAndRemoveUntil(context, '/home', ModalRoute.withName('/home'));

Note: use this method to some certain extent, because you might mess up your navigation history.注意:一定程度上使用此方法,因为您可能会弄乱您的导航历史记录。

Whenever the back button or Swipe gesture(iOS) is pressed, you will get a callback at onWillPop , which returns a Future .每当按下后退按钮滑动手势(iOS)时,您都会在onWillPop处收到一个回调,它返回一个Future If the Future returns true, the screen is popped(ie navigate to the previous screen), If it is false, then it doesn't navigate back.如果Future返回 true,则弹出屏幕(即导航到前一个屏幕),如果它为 false,则不会导航回来。

Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () {
        return Future.value(false);
      },
      child: Scaffold(
        appBar: AppBar(title: Text("Second Screen"),),
        body: Center(

And if you want to pop screen on a condition basis then declare如果你想根据条件弹出屏幕然后声明

bool shouldPop = true; // change this using setState() inside build on the requirement. 

  onWillPop: () {
        return Future.value(shouldPop? true: false);
      },

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 iOS 7禁用向后滑动 - iOS 7 disable the swipe back 在 iOS 7 中更改后退按钮会禁用滑动以返回导航 - Changing back button in iOS 7 disables swipe to navigate back 有没有办法在 iOS 的 Safari 中禁用向后滑动 animation? - Is there a a way to disable swipe back animation in Safari on iOS? 如何在 iOS 上的 UINavigationController 中禁用向后滑动手势 7 - How to disable back swipe gesture in UINavigationController on iOS 7 Flutter:iOS 带有数据的向后滑动手势 - Flutter: iOS swipe back gesture with data Ionic 4 仅在一页中禁用 iOS 向后滑动 - Ionic 4 Disable iOS Swipe Back in ONE PAGE ONLY iOS 7 - 有没有办法在 Safari 中禁用前后滑动功能? - iOS 7 - is there a way to disable the swipe back and forward functionality in Safari? 如何在iOS 8中的UINavigationController中禁用后退滑动手势? - How do disable back swipe gesture in UINavigationController in iOS 8? 有没有办法在反应原生 iOS 时有条件地禁用对 go 后退手势的滑动? - Is there a way to conditionally disable the swipe to go back gesture in react native iOS? 如何在 Flutter MaterialApp 中检测 iOS 向后滑动手势? - How to detect iOS back swipe gesture in Flutter MaterialApp?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM