iOS系统分享视图键盘弹起导致的WKWebView frame被自动放大的问题

[复制链接]
回帖奖励 7 金钱      回复本帖可获得 1 金钱奖励! 每人限 1 次
查看1289 | 回复3 | 2024-8-15 18:03:29 | 显示全部楼层 |阅读模式
本帖最后由 qq243559086 于 2024-8-15 16:37 编辑

相信做混合开发都会遇到的一个问题,iOS 的WKWebView 在键盘弹起后整个页面被自动放大,其实严格来说,这不是个事,这是一个苹果非常好的设计效果,对于小屏幕手机来说用户可以更清晰的看到自己的输入。但苹果这个坑爹玩意坏就坏在,它只管放大,不管还原。
没办法,在网上查到,在html中加入
  1. <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
复制代码
就能解决问题,试着加入一下,嗯~可以,解决,撒花~,撒花~,完美大结局。



可惜高兴的太早了,直到我弹出UIActivityViewController分享,并选择了备忘录,输入文字,弹出键盘,存储文字,退出分享,回来一看,傻眼了。WKWebView 又被放大了。我勒个去,不是,我在UIActivityViewController 页面上弹的键盘,关你WKWebView 什么事,你放大个der啊。这都是些什么事。鸿蒙,你要加油了,这个破系统,真是一刻也不想...,算了,还得靠他赏饭吃😫
这问题解决起来就棘手了,在网上首先查到:
  1. NSNotificationCenter *nc = NSNotificationCenter.defaultCenter;
  2. [nc removeObserver:self.webview name:UIKeyboardWillShowNotification object:nil];
  3. [nc removeObserver:self.webview name:UIKeyboardWillHideNotification object:nil];
  4. [nc removeObserver:self.webview name:UIKeyboardWillChangeFrameNotification object:nil];
  5. [nc removeObserver:self.webview name:UIKeyboardDidChangeFrameNotification object:nil];
复制代码
这几个是把 WKWebView 对键盘的监听移除。嗯~,试了一下,完全没用。
然后又查到:
  1. if (kSystemVersion < 12.0) {
  2.     if (@available(iOS 11.0, *)) {
  3.         _webview.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
  4.     }
  5. }
  6. if (@available(iOS 12.0, *)) {
  7.     _webview.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentAutomatic;
  8. }
复制代码
嗯~,试了一下,完全没用。

翻来覆去,覆来翻去,都是这几样解决方案。看来只能靠我自己动手丰衣足食了。

首先,我想到的是在UIActivityViewController页面消失后把WKWebView 的frame设置成屏幕frame大小。设置后WKWebView 的frame倒是和屏幕的frame一样大了,但效果傻眼了,它内部的子视图很多还是一样的放大状态,你看看,你看看,苹果你都干了些什么,你自己的bug,搞的我们焦头烂额的。总不能我去把所有的子视图的frame都还原吧,WKWebView 是系统API,不清楚内部实现,要是这么做了,WKWebView加载其他页面导致子视图全换了,又被放大了,那不白干了。每次都要自己重新设置frame,说不定FPS直线下降,严重影响用户体验。哎~,只能另辟蹊径了。

第二个我想到的办法是,如何一开始就不要让WKWebView接触到键盘事件。想来想去,只能在WKWebView 所在的UIViewController 上覆盖一层透明的UIViewController ,用覆盖的这层透明UIViewController去弹出UIActivityViewController, 然后在 UIActivityViewController 消失后删除覆盖的这层透明UIViewController,然后就有了:
  1. UIViewController vc; // 假设这个是 WKWebView 所在的UIViewController
  2. UIViewController *mvc = [UIViewController new]; // 覆盖层 UIViewController
  3. mvc.modalPresentationStyle = UIModalPresentationOverFullScreen;
  4. mvc.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
  5. // vc 先呈现 mvc
  6. [vc presentViewController:mvc animated:NO completion:^{
  7.     // 这里是 mvc 呈现后
  8.     // UIActivityViewController
  9.     UIActivityViewController *avc = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:nil];
  10.     // mvc 去显示 UIActivityViewController
  11.     [mvc presentViewController:avc animated:YES completion:nil];

  12.     avc.completionWithItemsHandler = ^(UIActivityType _Nullable activityType, BOOL completed, NSArray * _Nullable returnedItems, NSError * _Nullable activityError) {
  13.         // 判断avc消失了就执行删除覆盖层
  14.         [mvc dismissViewControllerAnimated:NO completion:nil];
  15.     };
  16. }];
复制代码
测试一下,效果完美。撒花~,撒花~。


回复

使用道具 举报

WT_0213 | 2024-8-15 18:29:38 | 显示全部楼层

回帖奖励 +1 金钱

回复

使用道具 举报

大猫的鱼 | 2024-8-16 17:42:14 | 显示全部楼层

回帖奖励 +1 金钱

不错不错
回复

使用道具 举报

一只呆头鹅 | 2024-8-23 15:24:10 | 显示全部楼层

回帖奖励 +1 金钱

不错不错
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则