macos下使用android studio环境开发flutter应用,使用了webview_flutter组件访问cesium地图页面,android环境下正常。ios模拟器和真机调试都出现了同一个问题:即普通访问页面、拖动地图正常,但如果该dart页面(包含webview_flutter组件)上加了floatingActionButton或者其他Stack布局的浮动组件,点击触发这些组件后,就无法再拖动webview_flutter页面中的地图。换用flutter_inappwebview问题依旧。
环境参数:
macOS版本:13.2.1 (22D68)。
android studio版本:2022.1.1 Patch 2;flutter插件版本:72.1.2;dart插件版本:221.6096。
Flutter SDK版本:3.3.9;Dart版本:2.18.5;flutter DevTools版本:2.15.0。
webview_flutter库版本: ^4.0.5;flutter_inappwebview库版本: ^5.7.2+3。
xcode版本:14.1 (14B47b)。
测试代码:
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
//#region platform_imports
// Import for Android features.
import 'package:webview_flutter_android/webview_flutter_android.dart';
// Import for iOS features.
import 'package:webview_flutter_wkwebview/webview_flutter_wkwebview.dart';
//#endregion platform_imports
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
late final WebViewController _controller;
@override void initState() {
//#region platform_features
late final PlatformWebViewControllerCreationParams params;
if (WebViewPlatform.instance is WebKitWebViewPlatform) {
params = WebKitWebViewControllerCreationParams(
allowsInlineMediaPlayback: true,
mediaTypesRequiringUserAction: const <PlaybackMediaTypes>{},
);
} else {
params = const PlatformWebViewControllerCreationParams();
}
final WebViewController controller = WebViewController.fromPlatformCreationParams(params);
//#endregion platform_features
controller
..setJavaScriptMode(JavaScriptMode.unrestricted)
..loadRequest(Uri.parse('https://www.sdgrxh.xyz/test/'));
//#region platform_features
if (controller.platform is AndroidWebViewController) {
AndroidWebViewController.enableDebugging(true);
(controller.platform as AndroidWebViewController)
.setMediaPlaybackRequiresUserGesture(false);
}
//#endregion platform_features
_controller = controller;
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: WebViewWidget(controller: _controller,),
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: const Icon(Icons.add),
),
);
}
}
测试网址:https://www.sdgrxh.xyz/test/
测试方法:运行上述代码后,在ios模拟器中自动显示cesium地图,此时拖动地图正常;点击一次右下方FAB按钮后,拖动地图操作将变成放大缩小;再次点击FAB后,拖动地图操作不再响应。
补充:访问其他网站没有问题,只有cesium地图出问题,难道是WebGL的问题?
参考GPT和自己的思路,这个问题可能与Flutter在iOS上的手势识别有关。iOS上有一些手势识别器(例如滑动返回)可能会与WebView的手势冲突,导致WebView页面无响应。在您的情况下,添加了浮动组件之后,它可能会干扰WebView的手势。
有几种方法可以尝试解决这个问题:
1 禁用WebView的手势识别器
尝试在WebView中禁用手势识别器,这样就可以避免与Flutter的手势冲突。在WebViewController对象上调用gesturesDisabled方法,将其设置为true。
2 禁用Flutter的手势识别器
禁用Flutter的手势识别器,这样就可以避免与WebView的手势冲突。可以使用GestureDetector组件的behavior属性将其设置为HitTestBehavior.translucent,这将允许手势穿透并传递到下面的WebView。
3 使用flutter_inappwebview插件
尝试使用flutter_inappwebview插件代替webview_flutter库。它提供了更多的手势控制选项,并且在iOS上具有更好的性能。
class _MyHomePageState extends State<MyHomePage> {
late final WebViewController _controller;
@override void initState() {
...
_controller = controller;
super.initState();
}
...
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: GestureDetector(
behavior: HitTestBehavior.translucent, // 允许手势穿透
child: WebViewWidget(controller: _controller,),
),
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: const Icon(Icons.add),
),
);
}
}
希望这可以帮助您解决问题。
该回答引用GPTᴼᴾᴱᴺᴬᴵ
根据您的描述,问题可能是由于iOS设备上WebView的手势识别和FloatingActionButton的手势识别之间存在冲突所导致的。您可以尝试使用一些手势识别的技巧来解决这个问题。
首先,您可以尝试禁用FloatingActionButton的手势识别,以确保WebView的手势识别得到正确响应。为此,您可以将FloatingActionButton包装在一个GestureDetector中,并禁用GestureDetector的手势识别,例如:
GestureDetector(
onTap: () {},
behavior: HitTestBehavior.translucent,
child: FloatingActionButton(
onPressed: () {},
child: Icon(Icons.add),
heroTag: null,
),
excludeFromSemantics: true,
)
在上面的代码中,behavior属性设置为HitTestBehavior.translucent,以允许手势穿透GestureDetector并直接触发WebView的手势识别。excludeFromSemantics属性设置为true,以避免将GestureDetector包装的控件添加到无障碍功能中。
另外,您也可以尝试使用一些手势识别的库,例如gesture_zoom_box,来实现更加灵活的手势控制。该库可以让您在任何控件上实现缩放和拖动手势,而无需处理手势冲突。
最后,如果您仍然无法解决问题,您可以考虑在iOS设备上使用WKWebView来代替UIWebView,因为UIWebView已经被苹果官方标记为已弃用。您可以通过将webview_flutter库的版本更新到最新版本来启用WKWebView支持,然后使用WebView.platform = TargetPlatform.iOS来显示WKWebView。这可能需要您重新调整您的代码,但它可能会解决手势冲突问题。
希望这些建议能够帮助您解决问题!
上述回答均未解决……
楼下 singsex 的方法也试了,不满足需求,页面上方需要有按钮,即使将按钮放置在页面外的工具条,也需要有drawer,drawer一出现,页面还是被锁死
楼下其他解决方法也试过了,将xcode升级到14.2,还是未解决该问题
很奇怪的是,地图虽然锁死了,但网页页面上的按钮却可以得到点击响应(示例网址上没有按钮,我本地测试的),另外,地图锁死不能拖动后,在flutter_inappwebview外包裹GestureDetector,仍然能够在onDoubleTap()中监听到双击事件
该思路参考GPT,仅供借鉴。
可以尝试将WebView的初始化和加载代码放在dispatch_async的块中,以确保它在主线程上运行:
dispatch_async(dispatch_get_main_queue(), ^{
// 在这里初始化和加载WebView
});
另外,也可以尝试设置WebView的UIDelegate和NavigationDelegate,并实现相应的方法来处理任何可能的交互和导航事件。
如果仍然存在问题,请检查是否有任何JavaScript代码或插件与您的WebView不兼容。可以通过禁用它们来进行测试。
最后,查看Xcode控制台是否有任何错误消息或警告。这些消息可能会提供有关问题所在的更多信息。
以下答案由GPT-3.5大模型与博主波罗歌共同编写:
这个问题可能是因为iOS浮动组件(FloatingActionButton)造成了UI渲染的冲突,导致WebView页面无法响应。可以尝试在iOS上使用Navigator等方法从WebView页面中移出浮动组件,或者使用Cupertino风格的浮动组件来代替常规的FloatingActionButton。
以下是可能的解决方法:
1.使用Navigator方法移出FAB
在iOS上,移除浮动组件可能会使页面重新进行布局和渲染,从而解决UI渲染冲突的问题。可以使用Navigator.pop(context)
方法来从WebView页面中移出浮动组件。
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.pop(context); //移出浮动组件
},
child: const Icon(Icons.add),
),
2.使用Cupertino风格的浮动组件
使用CupertinoButton.filled
来代替常规的浮动按钮。这个组件具有iOS设计风格,可能可以解决UI渲染冲突的问题。
floatingActionButton: SizedBox(
width: 70,
height: 70,
child: CupertinoButton.filled(
onPressed: () {},
child: const Icon(Icons.add),
),
),
如果以上方法无法解决问题,你还可以尝试在WebView页面中使用手势识别器,而不是浮动组件来实现操作。
return GestureDetector(
onTap: () {
print('tap');
},
child: WebViewWidget(controller: _controller,),
);
如果我的回答解决了您的问题,请采纳!
你可以尝试一下让h5去做这个fab按钮,应该是由于焦点丢失,导致webview无法获到焦点。
因为你现在已经用了webview了,这个fab完全可以让h5端同学做一下,或者你可以在Appbar里面加个按钮,测试一下。
如有帮助,望采纳。
实在不行就自定义FAB 估计是stack布局 遮挡了
js中webgl加速开了没
在你的代码中加入如下试试,然后重启模拟器,一定要重启让info.list生效,不然会报错。
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
该回答引用ChatGPT
根据您提供的信息,可能是因为在iOS模拟器和真机上,WebView组件与FloatingActionButton或Stack组件的布局结构不兼容,导致在点击FloatingActionButton或Stack组件后,无法再次拖动WebView页面中的地图。
尝试一些可能的解决方法:
1、在Scaffold的body属性中使用Stack布局,将WebView和FloatingActionButton放在同一个Stack中,而不是分别放在Scaffold的body属性和floatingActionButton属性中。
2、尝试在Scaffold的body属性中使用SingleChildScrollView或ListView等可滚动的组件包装WebView和FloatingActionButton,以确保两者的布局结构兼容。
3、如果上述方法不起作用,可以尝试使用Flutter中的GestureDetector组件来手动实现拖动地图的功能,而不是依赖于WebView中的手势识别。