alibaba / alibaba/flutter_boost

[Bug]: iOS 26 下 withContainer: false 页面侧滑会错误触发原生 pop,导致 FBFlutterViewContainer 被 pop

Open
#2,262 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Dart
Stars
7.2k
Forks
1.3k
PR merge metrics
No merged PRs in 30d

Description

### 请描述遇到的问题,以及您所期望的正确的结果

项目中使用 FlutterBoost 打开 Flutter 页面,Flutter 页面内部继续通过 withContainer:false 跳转到第二个 Flutter 页面。

在 iOS 26 之前,侧滑返回表现正常:
1. Flutter 容器顶层页面侧滑:返回原生页面
2. Flutter 容器内部第二层页面侧滑:只返回 Flutter 容器顶层页面

但在 iOS 26 上,Flutter 内部第二层页面侧滑时,会错误触发原生 UINavigationController.popViewController,导致整个 FBFlutterViewContainer 被 pop 回原生页面。

期望结果:
当 FlutterBoost 容器内 Flutter 页面栈数量大于 1 时,原生 UINavigationController 不应该 pop FBFlutterViewContainer,侧滑返回应该优先交给 Flutter 内部 Navigator 处理。

实际结果:
Flutter 页面 B 侧滑时,原生 UINavigationController.popViewController 被触发,整个 FBFlutterViewContainer 被 pop,页面直接返回到原生页面。

### 请说明如何操作会遇到上述问题

页面结构如下:

RootViewController: UINavigationController
└─ TabBarController
└─ 当前 Tab: UINavigationController
└─ FBFlutterViewContainer
└─ Flutter Navigator
├─ Flutter 页面 A
└─ Flutter 页面 B(withContainer:false)

复现步骤:

1. 原生页面 push 打开 Flutter 页面 A。
2. Flutter 页面 A 内部通过 withContainer:false 跳转到 Flutter 页面 B。
3. 在 Flutter 页面 B 上从左侧侧滑返回。
4. 预期应该只返回 Flutter 页面 A。
5. 实际在 iOS 26 上会直接返回到原生页面,整个 FBFlutterViewContainer 被 pop。

### 在下面填入关键复现代码

FlutterBoost 已经发送 enablePopGesture=false:

enablePopGesture enable=NO

但之后仍然触发了原生 pop:

Nav pop before animated=YES count=2 top=
Nav pop after result= count=1 top=

FlutterBoost 当前 iOS 侧只控制了:

self.navigationController.interactivePopGestureRecognizer.enabled = enable;

但 iOS 26 新增了:

UINavigationController.interactiveContentPopGestureRecognizer

该手势与 interactivePopGestureRecognizer 不是同一个手势。

### 复现的平台

iOS

### Flutter SDK版本

Flutter 3.41.0

### FlutterBoost版本

feature/adapt_3.35_version

### 是否延迟初始化FlutterBoost

No

### 解决方案

初步判断:iOS 26 新增的 UINavigationController.interactiveContentPopGestureRecognizer 可能绕过了 FlutterBoost 当前对 interactivePopGestureRecognizer 的控制。

FlutterBoost 当前在 enablePopGesture 事件中只处理了:

self.navigationController.interactivePopGestureRecognizer.enabled = enable;

但 iOS 26 上还需要考虑:

UINavigationController.interactiveContentPopGestureRecognizer

否则在 withContainer:false 的 Flutter 内部页面侧滑返回时,即使 interactivePopGestureRecognizer 已经被 FlutterBoost 禁用,interactiveContentPopGestureRecognizer 仍可能触发原生 UINavigationController.popViewController,导致 FBFlutterViewContainer 被错误 pop。

我们当前的临时解决方案是:在原生 FlutterBoostDelegate.pushFlutterRoute 创建并 push FBFlutterViewContainer 前,禁用 iOS 26 的 interactiveContentPopGestureRecognizer,保留 FlutterBoost 原本对 interactivePopGestureRecognizer 的控制逻辑。

临时代码如下:

private func setInteractiveContentPopGestureEnabled(_ enabled: Bool, navigationController: UINavigationController?) {
guard #available(iOS 26.0, *),
let navigationController = navigationController else {
return
}

let selector = NSSelectorFromString("interactiveContentPopGestureRecognizer")
guard navigationController.responds(to: selector),
let gesture = navigationController.value(forKey: "interactiveContentPopGestureRecognizer") as? UIGestureRecognizer else {
return
}

gesture.isEnabled = enabled
}

在 push Flutter 容器前调用:

setInteractiveContentPopGestureEnabled(false, navigationController: superVC.navigationController)
superVC.navigationController?.pushViewController(vc, animated: isAnimated)

目前验证后表现正常:
1. Flutter 容器顶层仍可通过原来的 interactivePopGestureRecognizer 侧滑返回原生
2. Flutter 容器内部第二层侧滑只返回 Flutter 顶层
3. 不再错误 pop 整个 FBFlutterViewContainer

希望 FlutterBoost 在 iOS 26 及以上系统中,除了控制 interactivePopGestureRecognizer,也能同步处理 interactiveContentPopGestureRecognizer,或者在 FBFlutterViewContainer 内部根据 Flutter 页面栈状态统一控制 iOS 26 新增的 content pop gesture。

Contributor guide

No contributing guide indexed for this repository

Research direction

Start at FlutterBoostDelegate.pushFlutterRoute and the enablePopGesture handling around FBFlutterViewContainer. Reproduce the withContainer:false navigation flow on iOS 26, then compare control of interactivePopGestureRecognizer with interactiveContentPopGestureRecognizer. Done means the outer container still supports its intended back gesture while an inner Flutter page returns only to the previous Flutter page.

Written by the indexing model from the issue text.

Assessment

Tech stack
dart, ios, swift
Domain
mobile
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
54/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.