【问题标题】:How to check if WkWebView finish loading in Objective-C?如何检查 WkWebView 是否在 Objective-C 中完成加载?
【发布时间】:2016-03-30 15:26:45
【问题描述】:

我想使用 WkWebView 加载 HTML 页面,并且我想在页面加载完成后立即显示该页面。只要它正在加载,我想在空视图上显示一个活动指示器。 我创建了两个视图,一个 loadingView 和一个 wkWebView。在页面加载时,我将加载视图作为子视图添加到 VC,并且在我想删除加载视图并添加 wkWebView 之后。这是我的代码:

    [self addSubview:_loadingView];
    _wkWebView = [[WKWebView alloc] initWithFrame:self.frame];
    _wkWebView.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, self.frame.size.height);

    //Send a request to wkUrlconnection
    NSURL *wkUrl = [NSURL URLWithString:self.wkUrlString];
    NSURLRequest *wkRequest = [NSURLRequest requestWithURL:wkUrl];

    //Here I want to check if it's loaded and then remove loadingView and add wkWebView
    [_wkWebView loadRequest:wkRequest];
    [self.loadingView removeFromSuperview];
    [self addSubview:_wkWebView];

谁能告诉我如何在加载时检查以及是否完成刷新 VC?谢谢你的回答。

【问题讨论】:

  • 您是否查看过delegate 模式以及它如何与WKWebView 上的navigationDelegate 属性一起使用?
  • 谢谢垫子。我需要这个。

标签: ios objective-c wkwebview wkwebviewconfiguration


【解决方案1】:

我认为WKNavigationDelegatewebView:didFinishNavigation: 委托回调正是您要寻找的。​​p>

在您开始加载时配置并显示您的活动指示器,然后在调用回调时停止并将其从视图中移除。

【讨论】:

  • 谢谢。这是一个很好的解决方案,但让我纠正你。 WkWebView 没有 WKWebViewDelegate。取而代之的是 WKNavigationDelegate。
  • 一个扩展问题,WebView 加载完成后能否得到类似 URLSession 的响应?
  • 该方法可能会为多个帧多次调用,所以它不起作用
  • 任何知道何时完全加载且方法不再调用的解决方案
  • webView:didFinishNavigation: 回调不会来大多数时间它不适合我
【解决方案2】:

对于遇到网页包含多个帧并因此执行多次加载而中断加载动画的问题的任何人,我已经实现了以下内容,它适用于我迄今为止遇到的所有情况:

斯威夫特:

var loadCount: Int = 0

override func viewDidLoad() {
    super.viewDidLoad()

    startLoading()
    webview.navigationDelegate = self
    let request = URLRequest(url: url)
    webview.load(request)
}

func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
    loadCount += 1
}

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {

    loadCount -= 1

    DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in
        if self?.loadCount == 0 {
            self?.stopLoading()
        }
    }

}

基本的想法是在您请求 url 之前启动加载动画,然后计算每个发出的请求,并仅在您的请求计数 == 0 时停止加载动画。这是在稍微延迟后完成的,因为我发现有些帧同步排队请求,因此下一次加载将在 0.1 秒延迟完成之前开始。

( ͡° ͜ʖ ͡°)

【讨论】:

  • 这可能无法正常工作,无法保证每次 didStartProvisionalNavigation 都会获得 didFinish 导航,因此在这种情况下计数永远不会为 0。
  • 在Objective C中怎么样,因为这就是问题的要求
【解决方案3】:

对于 Swift 4.2:

func webView(_ webView: WKWebView,
                 didFinish navigation: WKNavigation!){
        print("loaded")
}

确保在 didLoad(或类似的)中为 webView 设置委托

webView.navigationDelegate = self

【讨论】:

  • 但这不适用于 Objective C 的要求
  • 我知道。我的 Swift 两分钱,objC 已经死了 :)
  • 目标 C 没有死。只是闻起来很有趣。
  • 我确实非常喜欢它,但是当我回去时,我想念所有新的 swift 简洁和功能。 :(
  • 目标 C 永远不会消亡。我们中有些人支持将永远存在的遗留代码,就像那些在 1999 年不得不挖掘 COBOL 代码的可怜的混蛋一样。
【解决方案4】:
class WebViewVC: UIViewController {
    
    // MARK: IBOutlets
    @IBOutlet weak var webView: WKWebView!
    @IBOutlet weak var activityIndicator: UIActivityIndicatorView!
    
    // MARK: Life cycle
    override func viewDidLoad() {
        super.viewDidLoad()
        
        webView.navigationDelegate = self
        loadWebsite()
    }
}

// MARK: WKWebView
extension WebViewVC: WKNavigationDelegate {
    func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
        activityIndicator.startAnimating()
    }
    
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        activityIndicator.stopAnimating()
    }
}

// MARK: Private methods
extension WebViewVC {
    private func loadWebsite() {
        guard let url = URL(string: "google.com") else { return }
        
        let urlRequest = URLRequest(url: url)
        webView.load(urlRequest)
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-12-13
    • 1970-01-01
    • 1970-01-01
    • 2019-01-27
    • 2012-01-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多