You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中如何修改iOS端的侧滑返回手势滑动方向

Flutter实现iOS端右边缘左滑返回的方案

Flutter自带的CupertinoPageRoute默认仅支持左边缘右滑触发返回,只需自定义路由逻辑替换手势识别规则即可实现反向侧滑返回。


1. 自定义支持右滑返回的路由类

直接继承CupertinoPageRoute,重写手势检测逻辑,将触发区域改为右边缘,滑动方向改为左滑:

import 'package:flutter/cupertino.dart';
import 'package:flutter/gestures.dart';

class RightBackCupertinoRoute<T> extends CupertinoPageRoute<T> {
  RightBackCupertinoRoute({
    required super.builder,
    super.settings,
    super.maintainState = true,
    super.fullscreenDialog = false,
  });

  @override
  Widget buildTransitions(BuildContext context, Animation<double> animation,
      Animation<double> secondaryAnimation, Widget child) {
    // 全屏弹窗保持原生逻辑,不添加右滑返回
    if (fullscreenDialog) {
      return super.buildTransitions(context, animation, secondaryAnimation, child);
    }
    return _RightBackGestureWrapper(
      route: this,
      child: super.buildTransitions(context, animation, secondaryAnimation, child),
    );
  }
}

class _RightBackGestureWrapper extends StatefulWidget {
  const _RightBackGestureWrapper({required this.route, required this.child});

  final CupertinoPageRoute route;
  final Widget child;

  @override
  State<_RightBackGestureWrapper> createState() => _RightBackGestureWrapperState();
}

class _RightBackGestureWrapperState extends State<_RightBackGestureWrapper> {
  late HorizontalDragGestureRecognizer _dragRecognizer;

  @override
  void initState() {
    super.initState();
    _dragRecognizer = HorizontalDragGestureRecognizer(debugOwner: this)
      ..onStart = _onDragStart
      ..onUpdate = _onDragUpdate
      ..onEnd = _onDragEnd
      ..onCancel = _onDragCancel;
  }

  @override
  void dispose() {
    _dragRecognizer.dispose();
    super.dispose();
  }

  /// 仅响应右边缘20dp范围内的触摸
  bool _isValidTouch(Offset localPos) {
    return localPos.dx > MediaQuery.of(context).size.width - 20;
  }

  void _onDragStart(DragStartDetails details) {
    if (!_isValidTouch(details.localPosition)) return;
    widget.route.didStartUserGesture();
  }

  void _onDragUpdate(DragUpdateDetails details) {
    if (!widget.route.popGestureIsActive) return;
    // 左滑时减小动画值,对应页面向左滑出的效果
    widget.route.controller!.value -= details.primaryDelta! / MediaQuery.of(context).size.width;
  }

  void _onDragEnd(DragEndDetails details) {
    if (!widget.route.popGestureIsActive) return;
    // 滑动速度超过阈值/滑动距离超过页面一半即触发返回
    const minSwipeVelocity = 365.0;
    final swipeSpeed = details.velocity.pixelsPerSecond.dx.abs();
    if (swipeSpeed > minSwipeVelocity || widget.route.controller!.value < 0.5) {
      widget.route.navigator?.pop();
    } else {
      widget.route.controller!.forward();
    }
    widget.route.didStopUserGesture();
  }

  void _onDragCancel() {
    if (widget.route.popGestureIsActive) {
      widget.route.didStopUserGesture();
    }
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        widget.child,
        Positioned.fill(
          child: Listener(
            onPointerDown: (event) {
              if (widget.route.popGestureEnabled && _isValidTouch(event.localPosition)) {
                _dragRecognizer.addPointer(event);
              }
            },
          ),
        ),
      ],
    );
  }
}

2. 路由使用方式

单页面跳转替换

跳转页面时直接用自定义路由替换默认的CupertinoPageRoute即可:

Navigator.push(
  context,
  RightBackCupertinoRoute(
    builder: (context) => const TargetPage(),
  ),
);

全局生效配置

在根组件的onGenerateRoute中统一配置,所有页面自动支持右滑返回:

CupertinoApp(
  // 其他配置省略
  onGenerateRoute: (settings) {
    switch (settings.name) {
      case '/home':
        return RightBackCupertinoRoute(
          builder: (context) => const HomePage(),
          settings: settings,
        );
      case '/detail':
        return RightBackCupertinoRoute(
          builder: (context) => const DetailPage(),
          settings: settings,
        );
      default:
        return RightBackCupertinoRoute(
          builder: (context) => const HomePage(),
          settings: settings,
        );
    }
  },
)

可选调整项

  • 修改代码中20的数值,可自定义右边缘手势响应区域的宽度
  • 调整minSwipeVelocity的数值,可修改触发返回需要的最小滑动速度

内容的提问来源于stack exchange,提问作者Ardeshir ojan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 19:09:03