一起養成寫作習慣!這是我參與「掘金日新計劃 · 4 月更文挑戰」的第3天,點選檢視活動詳情。
前言
Avoiding iOS bug:UIWebView with file input doesn‘t work in modal view controller
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICN4ETMfdHLkVGepZ2XtxSZ6l2clJ3LcBnYldHL0FWby9mZvwVPrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdsAjMfd3bkFGazxCMx8VesATMfhHLlN3XnxCMz8FdsYkRGZkRG9lcvx2bjxSa2EWNhJTW1AlUxEFeVRUUfRHelRHL2EzXlpXazxyayFWbyVGdhd3LcV2Zh1Wa9M3clN2byBXLzN3btg3PwJWZ35SMxEzN3AzNxYGZ3IDOlNTNyYzX3QDNzYTMxEzLcRDMyIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.webp)
github.com/zhangkn/KNU…
- 應用場景:modal UIWebView and camera/image picker
由于蘋果模态的特性,當模态出N個ViewController之後,隻需要dismiss任意一個,都會dismiss它之後的所有模态試圖 。
是以特性會導緻的問題:
modal模态出來的UIViewControllerWebView的H5彈出Camera/ImagePicker 時,當UIDocumentMenuViewController消失的時候會導緻WebView 所在的控制器也被幹掉。
- 解決思路:使dismissViewControllerAnimated調用一次,或者讓UIDocumentMenuViewController找不到presentingViewController
基礎概念:
1、presentedViewController :The view controller that is presented by this view controller, or one of its ancestors in the view controller hierarchy.
2、presentingViewController: The view controller that presented this view controller (or its farthest ancestor.)
I 解決WebVC調攝像頭之後,dismiss掉的問題
解決包含WebView的控制器調攝像頭之後被UIDocumentMenuViewController幹掉的問題
1.1 問題分析
UIDocumentMenuViewController 消失時調用的不僅調用了自己的,dismissViewControllerAnimated,還調用了,上層或者上上層presentingViewController的dismissViewControllerAnimated。
即會循環調用modal 方式的個個層級的dismissViewControllerAnimated,讓所有的控制器消失。
是以當使用者選擇takePhoto或者photoLibrary的時候,會導緻被modal出來的webView 所在的控制器也會銷毀。
1.2 問題解決思路
隻讓UIDocumentMenuViewController 對象調用自己的dismissViewControllerAnimated,或者讓UIDocumentMenuViewController找不到presentingViewController即可。
II 解決方案
2.1 方案1:隻讓UIDocumentMenuViewController 對象調用自己的dismissViewControllerAnimated方法
- 隻讓UIDocumentMenuViewController 對象調用自己的dismissViewControllerAnimated,不讓加載H5 網頁的控制器被剛掉(推薦使用此方法)
目前ViewController的所有presentedViewController都正常執行dismissViewControllerAnimated,目前ViewController本身執行dismissViewControllerAnimated,不進行dismiss,不做處理。
除非使用者自己要求退出self.exitKNBaseWebViewControllerflagged = yes 或者 當想dismiss掉目前ViewController的時候,不能調用本身的dismissViewControllerAnimated ,直接調用父類的dismissViewControllerAnimated
重寫擁有web View控制器的dismiss 方法
#if 1
-(void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion
{
/**presentedViewController 本控制器即将present展示的控制器
思路,第一次 UIDocumentMenuViewController 展示拍照和photo界面的控制器 消失
第二次 self.presentedViewController nil 此時不調用dismissViewControllerAnimated,, 如果自己要消失的話,需要新增個辨別,表示是使用者要傳回
第三次 UIImagePickerController 相冊、拍照控制器 消失
*/
if ( self.presentedViewController )
{
[super dismissViewControllerAnimated:flag completion:completion];
}
// if (self.exitKNBaseWebViewControllerflagged) {
// self.exitKNBaseWebViewControllerflagged = NO;
// [super dismissViewControllerAnimated:flag completion:completion];
// }
}
#endif
2.2 方案2:使UIDocumentMenuViewController找不到presentingViewController
解決方法就是不讓UIDocumentMenuViewController找到上層或者上上層的任意presentingViewController
/**
從控制器展示的方法presentViewController,解決
方法二,使UIDocumentMenuViewController找不到presentingViewController
*/
- (UIViewController *)presentingViewController {
// Avoiding iOS bug. UIWebView with file input doesn't work in modal view controller
if (_flagged) {
return nil;
} else {
return [super presentingViewController];
}
}
- (void)presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion {
// Avoiding iOS bug. UIWebView with file input doesn't work in modal view controller
if ([viewControllerToPresent isKindOfClass:[UIDocumentMenuViewController class]]
||[viewControllerToPresent isKindOfClass:[UIImagePickerController class]]) {
_flagged = YES;
}
[super presentViewController:viewControllerToPresent animated:flag completion:completion];
}
2.3 demo 用法:
- 修改測試位址為你自己的URL
NSString *const PRODUCTIONBaseURL = @"https://kunnan.blog. .net/article/details/103902362";
-
github.com/zhangkn/KNU…