导致问题的html代码是这一句:<input type = "file" name = "file"> 调用app的UIDocumentMenuViewController控制
问题发生场景:VC presentViewController 显示 webVC;
或者VC presentViewController 显示NVC,webVC在NVC上
这时候在H5上的 input type = "file" 触发后会导致UIDocumentMenuViewController 和 pre出来的VC(显示webVC的界面)两个直接dismis掉,
控制台会打印这么句警告: Warning: Attempt to present <UIImagePickerController: 0x1018a0600> on <XXController: 0x100506020> whose view is not in the window hierarchy!
个人觉得这是apple的一个bug,应该有开发者反馈了才对,但是到目前WKWebView, UIWebView还存在这个问题,具体原因不晓得,坐等apple修复,在这之前可以参考我的处理方式,把那demo里的UIViewController+Dismis_FileUploadPanel .h和.m文件拖到项目里就ok了,不需要额外代码。修复处理逻辑看下文:
经过分析,发现是WKFileUploadPanel(或 UIWebFileUploadPanel)这么个东西的 _dismisDisplayAnimated: 方法执行的,直接代码是在UIDocumentMenuViewController控制器关闭后的completion内触发。
分析后发现 UIDocumentMenuViewController 和 webVC 之间并没有什么关系(pre关系),只是和WKFileUploadPanel(或 UIWebFileUploadPanel) 这货有关系(delegate关系),基于这一点结合runtime切入,在presentViewController:animated: 时候对特殊UIDocumentMenuViewController进行标记,
由于cancel是由UIDocumentMenuViewController发起的,所以也对其进行标记。
然后dismissViewControllerAnimated:animated:时候的completion对标记对象进行区分处理,由于两次dismis是两个无关的vc顺序执行,所以用一个静态变量dismisFromFileUploadPanel 来标记是否是UIDocumentMenuViewController之后的dismis。
标记的目的是其它正常的dismis可以正确执行,避免其它bug出现。
更新:新增选择图片拦截,可知道选择的图片信息,修复选择图片拦截bug
分析发现图片文件选择走的是UIImagePickerController,而UIImagePickerController是通过代理返回结果集,那么在FileUploadPanel内部就必然有回调方法,否则无法完成图片获取操作
之前尝试runtime对WKFileUploadPanel 或 UIWebFileUploadPanel 采用方法替换拦截测试不可行,
新的拦截思路采用代理拦截器实现,在UIImagePickerController setDelegate:时候增加_UIImagePickerController_IFUP 拦截[imagePickerController: didFinishPickingMediaWithInfo:]代理事件
具体实现看demo:https://github.com/youlianchun/WebView_FileUploadBug