【问题标题】:How do I add Pull to Refresh in WebView?如何在 WebView 中添加 Pull to Refresh?
【发布时间】:2016-03-28 05:20:41
【问题描述】:

我对开发非常陌生。我正在构建一个 WebView,我希望它具有刷新功能。我该如何快速做到这一点?

我在 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()

}

【问题讨论】:

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


    【解决方案1】:

    您的代码有问题,您在必须遵循的ViewDidLoad 方法中添加了两个 Web 视图 Delegate,并检查以下 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()
    
        }
    
    }
    

    【讨论】:

    • 非常感谢。再说一次,我刚开始学习代码,我还在上高中,所以感谢您的宝贵时间
    【解决方案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))
        }
    }
    

    【讨论】:

    • 非常有帮助。谢谢
    【解决方案3】:

    以下代码会将刷新控件放在 webview 的滚动视图中。最初它将加载 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))
    }
    }
    

    【讨论】:

    • 这段代码使用 Swift 4 对我有用。谢谢!我在项目中唯一需要更改的地方(出于某种原因,我不确定,因为我是 Swift 新手):@objc func refreshControlClicked(){ print("refresh triggered") refreshControl.endRefreshing() }
    【解决方案4】:

    你可以用这个

    1. 在 DidLoad 方法中写这个

      webViewHome.scrollView.delegate = self; 
      

      然后写这个方法

      #pragma mark Scrollview 委托

      • (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)速度 targetContentOffset:(inout CGPoint *)targetContentOffset{ 如果(scrollView.contentOffset.y

    注意:请确保您没有将滚动视图反弹属性设置为否,否则此方法将不会调用

    【讨论】:

      猜你喜欢
      • 2016-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-11
      • 1970-01-01
      • 2011-06-02
      • 2016-03-23
      • 1970-01-01
      相关资源
      最近更新 更多