首页 文章

WKWebView操作表在被解雇后解除显示视图控制器

提问于
浏览
6

我有一个嵌入在NavigationController中的视图控制器(WKWebViewController) . 这个ViewController提供了一个WKWebView . 导航到任何网页后;并且在长按任何检测到的内容(例如电话号码或链接)时,会显示一个操作表,其中包含复制,共享等选项 . 问题是当此操作表被取消时,WKWebViewController随之被解雇显示根ViewController!无论选择是什么,它都可以复制,取消,甚至可以点击屏幕上的任何位置 .

我试过覆盖“现在(_ viewControllerToPresent:UIViewController,动画标志:Bool,完成:(() - > Void)?= nil)" and the " dismiss(动画标志:Bool,完成:(() - > Void)? )“试图了解发生了什么,但后来意识到动作表没有被其父视图控制器(WKWebViewController)解雇,事实上我在根视图控制器上做了同样的事情,发现它是没有呈现在它上面 .

我已经做了很多搜索,试图了解导致这种行为的原因,我甚至用一个简单的WKWebView构建了一个新项目,但总是遇到同样的问题 .

这是代码:

import UIKit; import WebKit
class WKWebViewController: UIViewController, WKUIDelegate, WKNavigationDelegate {

var destinationUrlString: String?
var myWebView: WKWebView!

override func viewDidLoad() {
    super.viewDidLoad()

    let webConfiguration = WKWebViewConfiguration()
    webConfiguration.dataDetectorTypes = []
    let origin = CGPoint(x: 0, y: 0)
    let size  = CGSize(width: view.frame.size.width, height: view.frame.size.height)
    myWebView = WKWebView(frame: .init(origin: origin, size: size), configuration: webConfiguration)
    myWebView.uiDelegate = self
    myWebView.navigationDelegate = self
    myWebView.allowsLinkPreview = false
    view = myWebView

    destinationUrlString = "https://www.stackoverflow.com"
    guard let url = URL(string: destinationUrlString!) else {return}
    print(url)
    let request = URLRequest(url: url)
    myWebView.load(request)
}
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
    //show progress indicator
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    //dismiss progress indicator
}
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
    //show error
}
func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
    //show error
}
}

我还附上了一个显示问题的GIF:

enter image description here

我正在使用Xcode 9.3(9E145)和Swift 4.1 .

我错过了什么吗?怎么解决这个问题?任何帮助将非常感激 .

2 回答

  • 7

    我遇到了同样的问题 .

    为了处理这种情况,在 UIViewController 层次结构的根视图控制器中(在你的情况下,这将是"Root View Controller" - 注意,在许多情况下它可能是 UINavgiationController ,你必须将其子类化)覆盖 dismissViewControllerAnimated:completion: 来处理多次使用 WKWebView 调用dismiss .

    Objective-C

    @property (weak) UIViewController *lastPresentedController;
    
    - (void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion
    {
        // WKWebView actions sheets workaround
        if (self.presentedViewController && self.lastPresentedController != self.presentedViewController ) {
            self.lastPresentedController = self.presentedViewController;
            [self.presentedViewController dismissViewControllerAnimated:YES completion:^{
                if( completion ) {
                    completion();
                }
                self.lastPresentedController = nil;
            }];
        } else if( !self.lastPresentedController) {
            [super dismissViewControllerAnimated:flag completion:completion];
        }
    }
    

    Swift

    private weak var lastPresentedController : UIViewController?
    
    override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) {
        // WKWebView actions sheets workaround
        if presentedViewController != nil && lastPresentedController != presentedViewController  {
            lastPresentedController = presentedViewController;
            presentedViewController?.dismiss(animated: flag, completion: {
                completion?();
                self.lastPresentedController = nil;
            });
    
        } else if lastPresentedController == nil {
            super.dismiss(animated: flag, completion: completion);
        }
    }
    
  • 1

    这必须是一个错误 . 如果在覆盖Web视图的viewController中覆盖dismiss,则当用户从操作表中选择任何操作时,将调用它 . 如果在dismiss重写中放置断点,则可以看到presentViewController的类型为WKActionSheet,它是一个内部类 . 他们're likely calling dismiss to close the action sheet, which is then trickling up to and dismissing our view controller housing the web view. You can return from within that function to prevent the closing, but then the action they chose also doesn'发生了 .

    如果您不想提交雷达,请告诉我,我会 .

相关问题