registerPopGestureCallback static method

void registerPopGestureCallback(
  1. VoidCallback callback,
  2. BuildContext context
)

注册左滑返回手势的回调函数

当 iOS 系统检测到左滑返回手势时,会调用栈顶的回调函数。 多个页面可以同时注册回调,只有栈顶(最后注册)的回调会被调用。

参数:

  • context: 注册回调时的 BuildContext,作为回调的唯一标识, 同时用于检查页面是否还在顶层

使用场景:

  • 多个页面都需要拦截返回手势时,使用此方法可以避免回调覆盖
  • 组件销毁时需要清理回调,避免内存泄漏
  • 当路由是 A->B->C,B 页面注册了回调,C 页面没有注册回调时, 只有 B 页面还在顶层时才会调用 B 页面的回调

重要提示

  1. 必须在 didChangeDependencies() 中调用,不要在 initState() 中调用
  2. 使用 _isRegistered 标志防止重复注册,避免 InheritedWidget 更新时重复注册导致顺序混乱
  3. 必须在 dispose() 中注销回调,避免内存泄漏
  4. BuildContext 在 State 生命周期中是稳定的,不会因为 setState() 或 didChangeDependencies() 而改变

示例:

class MyPage extends StatefulWidget {
  @override
  State<MyPage> createState() => _MyPageState();
}

class _MyPageState extends State<MyPage> {
  bool _isRegistered = false;  // ✅ 重要:使用标志位防止重复注册

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    // ✅ 只在第一次调用时注册,避免 InheritedWidget 更新时重复注册
    if (!_isRegistered) {
      PopscopeIos.registerPopGestureCallback(() {
        print('检测到左滑返回手势');
        // 处理返回逻辑
        Navigator.maybePop(context);
      }, context);
      _isRegistered = true;
    }
  }

  @override
  void dispose() {
    // ✅ 必须注销回调
    if (_isRegistered) {
      PopscopeIos.unregisterPopGestureCallback(context);
    }
    super.dispose();
  }
}

错误示例(不要这样做)

// ❌ 错误:在 initState 中注册(context 可能未准备好)
@override
void initState() {
  super.initState();
  PopscopeIos.registerPopGestureCallback(() { ... }, context);
}

// ❌ 错误:没有使用 _isRegistered 标志(可能重复注册)
@override
void didChangeDependencies() {
  super.didChangeDependencies();
  PopscopeIos.registerPopGestureCallback(() { ... }, context);  // 每次都会注册!
}

// ❌ 错误:忘记在 dispose 中注销(内存泄漏)
@override
void dispose() {
  super.dispose();  // 忘记注销回调
}

Implementation

static void registerPopGestureCallback(
  VoidCallback callback,
  BuildContext context,
) {
  assert(
    context.mounted,
    'Cannot register callback with unmounted context. '
    'Make sure to call this method in didChangeDependencies() with a valid BuildContext.',
  );

  PopscopeIosPlatform.instance.registerPopGestureCallback(callback, context);
  PopscopeLogger.info(
    'registerPopGestureCallback context: ${context.hashCode}',
  );
}