How do I add Pull to Refresh in WebView?

2020-04-14 07:23发布

I'm very new to developing. I'm building a WebView and I want it to have pull to refresh capabilities. How do I go about doing that in swift?

My code in the View Controller is

@IBOutlet var webView: UIWebView!

override func viewDidLoad() {
    super.viewDidLoad()

    func webViewDidFinishLoad(webView: UIWebView) {
        UIApplication.sharedApplication().networkActivityIndicatorVisible = false
    }

    func webViewDidStartLoad(webView: UIWebView) {
        UIApplication.sharedApplication().networkActivityIndicatorVisible = true
    }

    let url = NSURL (string: "https://www.foo.com");
    let requestObj = NSURLRequest(URL: url!);
    webView.loadRequest(requestObj);
    NSUserDefaults.standardUserDefaults().registerDefaults(["UserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/601.5.17 (KHTML, like Gecko) Version/9.1 Safari/601.5.17"])
}


override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()

}

4条回答
家丑人穷心不美
2楼-- · 2020-04-14 07:59

Your code is buggy you added two Web view Delegate in side the ViewDidLoad method that must be following and check the following viewDidLoad code for adding Pull to Refresh in web view:

@IBOutlet var webView: UIWebView!

 var refController:UIRefreshControl = UIRefreshControl()

 override func viewDidLoad() {
    super.viewDidLoad()


    let url = NSURL (string: "https://www.foo.com");
    let requestObj = NSURLRequest(URL: url!);
    webView.loadRequest(requestObj);
    NSUserDefaults.standardUserDefaults().registerDefaults(["UserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/601.5.17 (KHTML, like Gecko) Version/9.1 Safari/601.5.17"])



    refController.bounds = CGRectMake(0, 50, refController.bounds.size.width, refController.bounds.size.height) 
    refController.addTarget(self, action: Selector("mymethodforref:"), forControlEvents: UIControlEvents.ValueChanged)
    refController.attributedTitle = NSAttributedString(string: "Pull to refresh")
    webView.scrollView.addSubview(refController)
    }



    func mymethodforref(refresh:UIRefreshControl){
      webView.reload()
      refController.endRefreshing()
   }
    func webViewDidFinishLoad(webView: UIWebView) {
        UIApplication.sharedApplication().networkActivityIndicatorVisible = false
    }

    func webViewDidStartLoad(webView: UIWebView) {
        UIApplication.sharedApplication().networkActivityIndicatorVisible = true
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()

    }

}
查看更多
Root(大扎)
3楼-- · 2020-04-14 08:08

You can use this one

  1. Write this in DidLoad method

    webViewHome.scrollView.delegate = self; 
    

    And then write this method

    #pragma mark Scrollview delegate

    • (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset{ if (scrollView.contentOffset.y < 0){ DLog(@" webview on top "); [self AgainCheckInternet:nil]; } }

Note: Please make sure you didn't set scrollview bounces property to No otherwise this method will not call

查看更多
Viruses.
4楼-- · 2020-04-14 08:09

Following code will put the refresh control in scrollview of webview.Initially it will load google.com. To see pull to refresh clearly I have set white color to the background of scroll view so it is clearly visible and on pull to refresh webview opens facebook page.

class ViewController: UIViewController,UIWebViewDelegate {

@IBOutlet weak var webView: UIWebView!

var refreshControl:UIRefreshControl?

override func viewDidLoad() {

    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    self.refreshControl = UIRefreshControl.init()
    refreshControl!.addTarget(self, action:#selector(refreshControlClicked), for: UIControlEvents.valueChanged)
    self.webView.scrollView.addSubview(self.refreshControl!)

    self.webView.scrollView.backgroundColor = UIColor.white

    self.webView.delegate = self


    let url:URL = URL.init(string:"https://www.google.com")!

    self.loadRequestWithUrl(URLRequest.init(url: url))

}


func webViewDidStartLoad(_ webView: UIWebView) {

    NSLog("website loaded")
}

func loadRequestWithUrl(_ urlRequest : URLRequest?){

    if(urlRequest != nil){

        self.webView.loadRequest(urlRequest!)
    }
}

func refreshControlClicked(){

    let url:URL = URL.init(string:"https://www.facebook.com")!

    self.loadRequestWithUrl(URLRequest.init(url: url))
}
}
查看更多
霸刀☆藐视天下
5楼-- · 2020-04-14 08:10

Details

  • Xcode 11.3.1, Swift 5.1

Solution

extension WKWebView {

    var refreshControl: UIRefreshControl? { (scrollView.getAllSubviews() as [UIRefreshControl]).first }

    enum PullToRefreshType {
        case none
        case embed
        case custom(target: Any, selector: Selector)
    }

    func setPullToRefresh(type: PullToRefreshType) {
        (scrollView.getAllSubviews() as [UIRefreshControl]).forEach { $0.removeFromSuperview() }
        switch type {
            case .none: break
            case .embed: _setPullToRefresh(target: self, selector: #selector(webViewPullToRefreshHandler(source:)))
            case .custom(let params): _setPullToRefresh(target: params.target, selector: params.selector)
        }
    }

    private func _setPullToRefresh(target: Any, selector: Selector) {
        let refreshControl = UIRefreshControl()
        refreshControl.addTarget(target, action: selector, for: .valueChanged)
        scrollView.addSubview(refreshControl)
    }

    @objc func webViewPullToRefreshHandler(source: UIRefreshControl) {
        guard let url = self.url else { source.endRefreshing(); return }
        load(URLRequest(url: url))
    }
}

// https://stackoverflow.com/a/47282118/4488252

extension UIView {

    class func getAllSubviews<T: UIView>(from parenView: UIView) -> [T] {
        return parenView.subviews.flatMap { subView -> [T] in
            var result = getAllSubviews(from: subView) as [T]
            if let view = subView as? T { result.append(view) }
            return result
        }
    }

    func getAllSubviews<T: UIView>() -> [T] { return UIView.getAllSubviews(from: self) as [T] }
}

Usage

Setup

import UIKit
import WebKit

class ViewController2: UIViewController {
    private weak var webView: WKWebView!
    override func viewDidLoad() {
        super.viewDidLoad()
        // ... create webView here
        webView.navigationDelegate = self
    }
}

// MARK: WKNavigationDelegate

extension ViewController2: WKNavigationDelegate {
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        webView.refreshControl?.endRefreshing()
    }

    func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
        webView.refreshControl?.endRefreshing()
    }

    func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
        webView.refreshControl?.endRefreshing()
    }
}

Activate pull to refresh (option 1)

 webView.setPullToRefresh(type: .embed)

Activate pull to refresh (option 2)

 @objc func customPullToRefreshHandler(source: UIRefreshControl) {
     guard let url = webView.url else { source.endRefreshing(); return }
     webView.load(URLRequest(url: url))
 }

 // ....

 webView.setPullToRefresh(type: .custom(target: self, selector: #selector(customPullToRefreshHandler(source:))))

Deactivate pull to refresh

 webView.setPullToRefresh(type: .none)

Full sample

Do not forget to paste here the solution code

import UIKit
import WebKit

class ViewController: UIViewController {

    private weak var webView: WKWebView!

    override func viewDidLoad() {
        super.viewDidLoad()
        createWebView()
        webView.load("https://google.com")

        // Way 1
        webView.setPullToRefresh(type: .embed)

        // Way 2
       // webView.setPullToRefresh(type: .custom(target: self, selector: #selector(customPullToRefreshHandler(source:))))
    }

    private func createWebView() {
        let webView = WKWebView(frame: .zero, configuration: .init())
        view.addSubview(webView)
        webView.navigationDelegate = self
        self.webView = webView
        webView.translatesAutoresizingMaskIntoConstraints = false
        webView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        webView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
        view.bottomAnchor.constraint(equalTo: webView.bottomAnchor).isActive = true
        view.rightAnchor.constraint(equalTo: webView.rightAnchor).isActive = true
    }

//    @objc func customPullToRefreshHandler(source: UIRefreshControl) {
//        guard let url = webView.url else { source.endRefreshing(); return }
//        webView.load(URLRequest(url: url))
//        print("WebView started loading")
//    }
}

// MARK: WKNavigationDelegate

extension ViewController: WKNavigationDelegate {
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        webView.refreshControl?.endRefreshing()
    }

    func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
        webView.refreshControl?.endRefreshing()
    }

    func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
        webView.refreshControl?.endRefreshing()
    }
}

extension WKWebView {
    func load(_ urlString: String) {
        guard let url = URL(string: urlString) else { return }
        load(URLRequest(url: url))
    }
}
查看更多
登录 后发表回答