【问题标题】:How to monitor WKWebView page load progress in Swift?如何在 Swift 中监控 WKWebView 页面加载进度?
【发布时间】:2017-12-27 07:28:56
【问题描述】:

这是我的代码:

@IBOutlet weak var webView: WKWebView!
@IBOutlet weak var progressView: UIProgressView!

override func viewDidLoad() {
    super.viewDidLoad()

    webView.uiDelegate = self
    webView.navigationDelegate = self

    webView.addObserver(self, forKeyPath: "estimatedProgress", options: .new, context: nil)        
}

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    if (keyPath == "estimatedProgress") {
        progressView.setProgress(Float(webView.estimatedProgress), animated: true)
        print(webView.estimatedProgress)
    }
}

但estimatedProgress 只显示两个浮点数(0.1 和1.0),我认为它不起作用。我使用了 Alamofire 进度,它以毫秒为单位发生变化,这使我的 UI 更好,但这段代码不能正常工作......

有人可以帮助我了解 webView 的进展吗?

【问题讨论】:

    标签: ios swift webkit xcode8


    【解决方案1】:

    斯威夫特 4.0

    @IBOutlet weak var webView: WKWebView!
    @IBOutlet weak var progressView: UIProgressView!
    override func viewDidLoad() {
        super.viewDidLoad()
    
        // load website or HTML page
        self.webView.load(NSURLRequest(url: URL(string: "https://www.apple.com")!) as URLRequest);
    
        //add observer to get estimated progress value
        self.webView.addObserver(self, forKeyPath: "estimatedProgress", options: .new, context: nil);
    }
    
    // Observe value
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        if keyPath == "estimatedProgress" {
            print(self.webView.estimatedProgress);
            self.progressView.progress = Float(self.webView.estimatedProgress);
        }
    }
    

    【讨论】:

      【解决方案2】:

      新的 Swift KVO 方法

      class ViewController: UIViewController {
      
          private lazy var webView = WKWebView()
          private var observation: NSKeyValueObservation?
      
          override func viewDidLoad() {
              super.viewDidLoad()
      
              observation = webView.observe(\WKWebView.estimatedProgress, options: .new) { _, change in
                  print("Loaded: \(change)")
              }
          }
      
          deinit {
              self.observation = nil
          }
      }
      

      【讨论】:

        【解决方案3】:

        这应该在 Swift 5 上正常工作:

        @IBOutlet weak var webView: WKWebView!
        @IBOutlet weak var progressView: UIProgressView!
        
        private var observation: NSKeyValueObservation? = nil
        
        override func viewDidLoad() {
            super.viewDidLoad()
        
            // load website or HTML page
            webView.load(NSURLRequest(url: URL(string: "https://www.apple.com")!) as URLRequest)
        
            // add observer to update estimated progress value
            observation = webView.observe(\.estimatedProgress, options: [.new]) { _, _ in
                self.progressView.progress = Float(self.webView.estimatedProgress)
            }
        }
        
        deinit {
            observation = nil
        }
        

        【讨论】:

          【解决方案4】:

          KVO 的 Objective-C 实现:

          -(void)viewDidLoad {
              [super viewDidLoad];
              [self.webView addObserver:self forKeyPath:NSStringFromSelector(@selector(estimatedProgress)) options:NSKeyValueObservingOptionNew context:NULL];
          }
          
          - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
              if ([keyPath isEqualToString:NSStringFromSelector(@selector(estimatedProgress))] && object == self.webView) {
                   self.progressView.alpha = 1.0;
                   [self.progressView setProgress:self.webView.estimatedProgress animated:YES];
          
                   if(self.webView.estimatedProgress >= 1.0f) {
                      [UIView animateWithDuration:0.3 delay:0.3 options:UIViewAnimationOptionCurveEaseOut animations:^{
                         [self.progressView setAlpha:0.0f];
                       } completion:^(BOOL finished) {
                         [self.progressView setProgress:0.0f animated:NO];
                      }];
                   }
          
              } else {
                  [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
              }
          }
          

          【讨论】:

            【解决方案5】:

            这是在 Swift 5 中,先导入 WebKit,然后

            //
            // ViewController.swift
            //
            
            @IBOutlet weak var webView: WKWebView!
            @IBOutlet weak var progressView: UIProgressView!
            
            override func viewDidLoad() {
                super.viewDidLoad()
            
                webView.uiDelegate = self
                webView.navigationDelegate = self
            
                // Change it here
                webView.addObserver(self, forKeyPath: #keyPath(WKWebView.estimatedProgress), options: .new, context: nil)        
            }
            
            override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
                if (keyPath == "estimatedProgress") {
                    // Also change it here
                    progressView.progress = Float(webView.estimatedProgress)
                    print(webView.estimatedProgress)
                }
            }
            

            希望它对你有用!

            【讨论】:

              猜你喜欢
              • 2019-01-27
              • 2018-01-08
              • 1970-01-01
              • 1970-01-01
              • 2019-01-29
              • 1970-01-01
              • 2021-06-23
              • 1970-01-01
              • 2012-08-20
              相关资源
              最近更新 更多