颤动:禁用滑动以在iOS中导航回来

时间:2018-03-07 21:38:55

标签: ios flutter

我是新手来讨论开发,并且当你有一个导航抽屉时,在iOS中发现它有点令人沮丧,当你滑动打开它时,它会执行Navigation.of(context).pop()。我想在iOS中禁用这种“轻扫到弹出”行为。我一直在阅读文档,但没有太多运气。

我确实看到了一个被称为WillPopScope的东西,似乎可以解决这个问题(github issue for it here),但我不能100%确定这是否是“正确”的做法(它似乎太复杂了...它应该更容易......就像根应用程序上的设置一样。)

8 个答案:

答案 0 :(得分:12)

WillPopScope 是执行此操作的正确方法。

不要责怪Flutter。责怪IOS没有后退按钮[插入邪恶的笑容]。

  

(看起来太复杂......它应该更容易......就像根应用程序上的设置一样)。

绝对不复杂。这是一个班轮:

new WillPopScope(
    onWillPop: () async {
      return false;
    },
    child: <children here>
)

配置文件会使更复杂,因为它更难以阅读和维护。

请记住在颤动中,一切都是小部件,而不仅仅是其中的一半。认证,配置,一切。

答案 1 :(得分:2)

好吧,所以@Darky说WillPopScope是一个完全可以接受的答案,但是,如果你想全面禁用它,你可以实际做到以下几点。

在xcode中打开您的项目,找到AppDelegate.swift并添加以下内容:

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

答案 2 :(得分:2)

我不太确定要实现什么,但是大多数时候,人们希望摆脱后台功能,因为他们不想让用户控制auth机制。例如,用户登录后,您不希望他们仅通过按后退按钮(或在iOS中向后滑动)导航到“登录”页面。可能的解决方案是使用pushNamedAndRemoveUntil

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

  

将具有给定名称的路线推到最   紧紧围绕给定的上下文,然后删除所有先前的   直到predicate返回true为止。

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

注意:请在某种程度上使用此方法,因为这可能会弄乱您的导航历史记录。

答案 3 :(得分:2)

我有一个类似的问题,我想阻止滑动以返回导航(默认弹出功能)。该代码有助于解决该问题。

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

此代码现在阻止了iOS和Android的向后导航(默认为向后按钮),而这正是我想要的。希望这会有所帮助。

答案 4 :(得分:1)

您可以在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>,
    );
  }

答案 5 :(得分:0)

我在这里还有一点。我只是在解决此问题,但是我还需要我的用户能够通过按一下AppBar上的“本机”后退按钮(不仅仅因为这个原因不想重新实现AppBar),而且我发现了这个小巧的小标志:userGestureInProgress在Navigator对象上,所以我使用的(并且假定是首选方式)是:

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

答案 6 :(得分:0)

MaterialPageRoute有一个名为fullscreenDialog的参数,默认情况下设置为false。设为true时,您的页面动画效果会有所不同,并且将无法在iOS上滑动以便返回。

用法示例:

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

在此处查看一些讨论:https://github.com/flutter/flutter/issues/14203

答案 7 :(得分:0)

每当按下后退按钮滑动手势(iOS)时,您都会在onWillPop处收到回调, 它返回一个 Future。如果 Future 返回 true,则弹出屏幕(即导航到上一个屏幕),如果为 false,则不会返回。

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

如果你想根据条件弹出屏幕,那么声明

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

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