fluttter 使用WillPopScope在ios设备失效的解决方案

840 阅读1分钟

使用到 WillPopScope 的时候,ios设备无法触发到左侧滑动事件,导致 onWillPop 事件不会被回调,这里可以使用手势监听事件解决,或者 重写WillPopScope组件(需要搭配ios路由 相对麻烦点,使用手势监听简单解决)

// 使用,和自带的 WillPopScope 一样使用
MyWillPopScope(
    child: page,
    onWillPop: async {
        // 此处处理你的逻辑
        return false;
    },
)
import 'dart:developer';
import 'dart:io';
import 'package:flutter/material.dart' as material;
import 'package:flutter/src/widgets/navigator.dart';
import 'package:flutter/src/widgets/routes.dart';
import 'package:flutter/src/widgets/framework.dart';

class MyWillPopScope extends StatefulWidget {
  const MyWillPopScope({
    super.key,
    required this.child,
    required this.onWillPop,
  });

  final Widget child;
  final WillPopCallback onWillPop;

  @override
  State<MyWillPopScope> createState() => _WillPopScopeState();
}

class _WillPopScopeState extends State<MyWillPopScope> {

  @override
  Widget build(BuildContext context) {
    if (Platform.isIOS) { 
        return material.Listener(
          onPointerUp: (details) async {
            bool safe1 = startDx < 30;
            bool safe2 = endDx < 30;
            log(
              "\n按下手指位置(${safe1 ? '安全区' : '非安全区'}) => $startDx"
              "\n手指抬起位置(${safe2 ? '安全区' : '非安全区'}) => $endDx",
              name: "WillPopScope",
            );
            // 左侧滑动、安全区
            if ((endDx > startDx) && safe1 && !safe2) {
              log("ios左侧滑动返回被拦截$endDx", name: "WillPopScope");
              widget.onWillPop();
            }
          },
          onPointerDown: (details) =>startDx = details.localPosition.dx,
          onPointerMove: (details) => endDx = details.localPosition.dx,
          child: material.WillPopScope(
            child: widget.child,
            onWillPop: () async => false,
          ),
        ); 
    } else { 
        widget.onWillPop().then((value) {
          log(value ?"android触发滑动返回":"android滑动返回被拦截", name: "WillPopScope");
        }); 
      return material.WillPopScope(
        onWillPop: widget.onWillPop,
        child: widget.child,
      );
    }
  }
}