Browse Source

fix(share): 修复 iOS 思维导图截图在非可见 tab 无法执行的问题

- 针对 iOS WKWebView 通信在不可见 tab 会暂停的问题,切换到思维导图 tab 以确保 WebView 可见
- 优化截图操作,等待 WebView 加载完成后执行 JavaScript 截图
- 增加对 WebView 加载状态的判断和处理
- 保持其他平台和可见 tab 直接执行截图逻辑
- 统一了音频文件不存在时的错误提示显示逻辑
weicu
lxm 7 months ago
parent
commit
9dfbc626ce
  1. 50
      lib/modules/meeting/views/bottomSheet/share_bottom_sheet.dart

50
lib/modules/meeting/views/bottomSheet/share_bottom_sheet.dart

@ -104,21 +104,48 @@ class _ShareBottomSheetState extends State<ShareBottomSheet> {
/// 处理思维导图操作(保存/分享)
/// [actionType] 操作类型,使用 [_MindMapActionType] 常量
///
/// iOS 特殊处理:
/// WKWebView 在 tab 不可见时,JavaScriptChannel(ImageChannel)通信会被暂停,
/// 导致 JS 的 postMessage 回调无法触发。
/// 修复方案:操作前先切换到思维导图 tab(index=3),确保 WebView 可见后再执行截图。
void _handleMindMapAction(int actionType) {
Get.back();
final mindMapController = Get.find<MindMapController>();
final meetingController = Get.find<MeetingDetailsController>();
mindMapController.imageType = actionType;
if (mindMapController.isWebViewReady) {
mindMapController.webViewController.runJavaScript('captureImage()');
// 思维导图 tab 的索引(TabBarView 第 4 个子项,index=3)
const int mindMapTabIndex = 3;
final bool isOnMindMapTab =
meetingController.tabController.index == mindMapTabIndex;
void runCapture() {
if (mindMapController.isWebViewReady) {
mindMapController.webViewController.runJavaScript('captureImage()');
} else {
// WebView 尚未加载完成,等待 onPageFinished 后执行
mindMapController.webViewController.setNavigationDelegate(
NavigationDelegate(
onPageFinished: (String url) {
mindMapController.isWebViewReady = true;
mindMapController.webViewController
.runJavaScript('captureImage()');
},
),
);
}
}
if (Platform.isIOS && !isOnMindMapTab) {
// iOS 上若当前不在思维导图 tab,先切换过去,确保 WKWebView 可见后再执行截图
meetingController.tabController.animateTo(mindMapTabIndex);
// 等待下一帧渲染完成后执行截图,避免 WebView 尚未完成布局
WidgetsBinding.instance.addPostFrameCallback((_) {
runCapture();
});
} else {
mindMapController.webViewController.setNavigationDelegate(
NavigationDelegate(
onPageFinished: (String url) {
mindMapController.isWebViewReady = true;
mindMapController.webViewController.runJavaScript('captureImage()');
},
),
);
runCapture();
}
}
@ -602,8 +629,7 @@ class _ShareBottomSheetState extends State<ShareBottomSheet> {
// 检查文件路径是否为空或文件是否存在
if (filepath.isEmpty || !File(filepath).existsSync()) {
Logger.error('分享文件失败: 文件不存在 (path: $filepath)');
EasyLoading.showToast(
'audioFileNotFound'.tr); // 对应中文:音频文件不存在
EasyLoading.showToast('audioFileNotFound'.tr); // 对应中文:音频文件不存在
return;
}
final result = await SharePlus.instance.share(ShareParams(

Loading…
Cancel
Save