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

xam8gpfp  于 2023-06-24  发布在  Flutter
关注(0)|答案(8)|浏览(862)

我是flutter开发的新手,发现在iOS中,当你有一个导航抽屉,当你滑动打开它时,它会执行Navigation.of(context).pop()。我想在iOS中禁用此“滑动弹出”行为。我一直在仔细阅读文档,但没有太多的运气。
我确实看到了一个被称为WillPopScope的东西,它似乎做的伎俩(github issue for it here),但我不是100%确定这是否是“正确”的方式来做它(它似乎太复杂了……应该更容易类似于根应用上的设置)。

68de4m5k

68de4m5k1#

WillPopScope正确的方法。
(it似乎太复杂了应该更容易类似于根应用上的设置)。
这并不复杂。这是一句台词:

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

配置文件会使事情变得更加复杂,因为它更难阅读和维护。
记住,在Flutter中,一切都是一个小部件,而不仅仅是其中的一半。身份验证,配置,所有的一切。

eanckbw9

eanckbw92#

我还有一点。我只是在解决这个问题,但我也需要我的用户能够通过按下AppBar上的“原生”返回按钮返回(不想仅仅因为这个而重新实现AppBar),我发现了这个利基小旗:userGestureInProgress,所以我使用的方法(假设是首选方法)是:

onWillPop: () async {
    return !Navigator.of(context).userGestureInProgress;
},
elcex8rz

elcex8rz3#

MaterialPageRoute有一个名为fullscreenDialog的参数,默认设置为false。当为true时,您的页面动画有点不同,并且在iOS上滑动返回将被禁用。
示例用法:

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

在这里看到一些讨论:https://github.com/flutter/flutter/issues/14203

uubf1zoe

uubf1zoe4#

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

tzdcorbm5#

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

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

这段代码现在阻止了iOS和Android的后退导航(默认后退按钮),这正是我要找的。希望这能帮上忙。

drnojrws

drnojrws6#

好吧,正如@Darky所说的,WillPopScope是一个完全可以接受的答案,但是,如果你想全面禁用它,你实际上可以这样做。
在xcode中打开你的项目,找到AppDelegate.swift并添加以下内容:

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

wmvff8tz7#

我不太确定你想实现什么,但大多数时候人们想摆脱后台功能,因为他们不想让用户控制身份验证机制。例如,用户登录后,您不希望他们仅按下后退按钮(或在iOS中向后滑动)导航到登录页面。一个可能的解决方案是使用pushNamedAndRemoveUntil
Future<T> pushNamedAndRemoveUntil<T extends Object>(BuildContext context, String newRouteName, RoutePredicate predicate)
将具有给定名称的路由推送到最紧密地包含给定上下文的导航器上,然后删除所有以前的路由,直到predicate返回true。
示例代码:pushNamedAndRemoveUntil(context, '/home', ModalRoute.withName('/home'));

注意:在一定程度上使用此方法,因为可能会弄乱导航历史。

cbwuti44

cbwuti448#

每次按下返回键Swipe手势(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);
      },

相关问题