如何在WebView中添加Pull to Refresh?

时间:2016-03-28 05:20:42

标签: ios swift webview uiwebview pull-to-refresh

我很擅长开发。我正在构建一个WebView,我希望它具有拉动刷新功能。我如何在swift中做到这一点?

我在View Controller中的代码是

@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 个答案:

答案 0 :(得分:3)

您的代码有问题,您在必须遵循的ViewDidLoad方法中添加了两个Web视图委托,并检查以下viewDidLoad代码,以便在Web视图中添加Pull to Refresh:

@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()

    }

}

答案 1 :(得分:2)

详细信息

  • Xcode 11.3.1,Swift 5.1

解决方案

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] }
}

用法

设置

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()
    }
}

激活拉动以刷新(选项1)

 webView.setPullToRefresh(type: .embed)

激活拉动以刷新(选项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:))))

停用拉动以刷新

 webView.setPullToRefresh(type: .none)

完整样本

不要忘记在此处粘贴解决方案代码

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))
    }
}

答案 2 :(得分:1)

以下代码会将刷新控件放在webview的scrollview中。最初它会加载google.com。为了看清楚刷新,我已经将白色设置为滚动视图的背景,因此它清晰可见,并且在拉动以刷新webview打开Facebook页面。

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))
}
}

答案 3 :(得分:1)

您可以使用此

  1. 在DidLoad方法中写入

    webViewHome.scrollView.delegate = self; 
    

    然后编写此方法

    #pragma标记Scrollview委托

    • (void)scrollViewWillEndDragging:(UIScrollView *)scrollView                  withVelocity:(CGPoint)力度           targetContentOffset :(输入CGPoint *)targetContentOffset {  如果(scrollView.contentOffset.y <0){      DLog(@“ webview位于顶部”);      [self AgainCheckInternet:nil];  } }

注意:请确保未将scrollview bounces属性设置为“否”,否则此方法将不会调用