本帖最后由 qq243559086 于 2024-8-15 16:37 编辑
相信做混合开发都会遇到的一个问题,iOS 的WKWebView 在键盘弹起后整个页面被自动放大,其实严格来说,这不是个事,这是一个苹果非常好的设计效果,对于小屏幕手机来说用户可以更清晰的看到自己的输入。但苹果这个坑爹玩意坏就坏在,它只管放大,不管还原。
没办法,在网上查到,在html中加入- <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
复制代码 就能解决问题,试着加入一下,嗯~可以,解决,撒花~,撒花~,完美大结局。
可惜高兴的太早了,直到我弹出UIActivityViewController分享,并选择了备忘录,输入文字,弹出键盘,存储文字,退出分享,回来一看,傻眼了。WKWebView 又被放大了。我勒个去,不是,我在UIActivityViewController 页面上弹的键盘,关你WKWebView 什么事,你放大个der啊。这都是些什么事。鸿蒙,你要加油了,这个破系统,真是一刻也不想...,算了,还得靠他赏饭吃😫。
这问题解决起来就棘手了,在网上首先查到:
- NSNotificationCenter *nc = NSNotificationCenter.defaultCenter;
- [nc removeObserver:self.webview name:UIKeyboardWillShowNotification object:nil];
- [nc removeObserver:self.webview name:UIKeyboardWillHideNotification object:nil];
- [nc removeObserver:self.webview name:UIKeyboardWillChangeFrameNotification object:nil];
- [nc removeObserver:self.webview name:UIKeyboardDidChangeFrameNotification object:nil];
复制代码 这几个是把 WKWebView 对键盘的监听移除。嗯~,试了一下,完全没用。
然后又查到:
- if (kSystemVersion < 12.0) {
- if (@available(iOS 11.0, *)) {
- _webview.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
- }
- }
- if (@available(iOS 12.0, *)) {
- _webview.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentAutomatic;
- }
复制代码 嗯~,试了一下,完全没用。
翻来覆去,覆来翻去,都是这几样解决方案。看来只能靠我自己动手丰衣足食了。
首先,我想到的是在UIActivityViewController页面消失后把WKWebView 的frame设置成屏幕frame大小。设置后WKWebView 的frame倒是和屏幕的frame一样大了,但效果傻眼了,它内部的子视图很多还是一样的放大状态,你看看,你看看,苹果你都干了些什么,你自己的bug,搞的我们焦头烂额的。总不能我去把所有的子视图的frame都还原吧,WKWebView 是系统API,不清楚内部实现,要是这么做了,WKWebView加载其他页面导致子视图全换了,又被放大了,那不白干了。每次都要自己重新设置frame,说不定FPS直线下降,严重影响用户体验。哎~,只能另辟蹊径了。
第二个我想到的办法是,如何一开始就不要让WKWebView接触到键盘事件。想来想去,只能在WKWebView 所在的UIViewController 上覆盖一层透明的UIViewController ,用覆盖的这层透明UIViewController去弹出UIActivityViewController, 然后在 UIActivityViewController 消失后删除覆盖的这层透明UIViewController,然后就有了:
- UIViewController vc; // 假设这个是 WKWebView 所在的UIViewController
- UIViewController *mvc = [UIViewController new]; // 覆盖层 UIViewController
- mvc.modalPresentationStyle = UIModalPresentationOverFullScreen;
- mvc.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
- // vc 先呈现 mvc
- [vc presentViewController:mvc animated:NO completion:^{
- // 这里是 mvc 呈现后
- // UIActivityViewController
- UIActivityViewController *avc = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:nil];
- // mvc 去显示 UIActivityViewController
- [mvc presentViewController:avc animated:YES completion:nil];
- avc.completionWithItemsHandler = ^(UIActivityType _Nullable activityType, BOOL completed, NSArray * _Nullable returnedItems, NSError * _Nullable activityError) {
- // 判断avc消失了就执行删除覆盖层
- [mvc dismissViewControllerAnimated:NO completion:nil];
- };
- }];
复制代码 测试一下,效果完美。撒花~,撒花~。
|
|