使用UIRefreshControl来刷新UIWebView。

14

我在iOS 6中看到了UIRefreshControl,我的疑问是是否可以通过向下拉动WebView并使其弹出来像邮件一样来刷新它? 我使用的代码是rabih是WebView:

UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
    [refreshControl addTarget:self action:@selector(handleRefresh:) forControlEvents:UIControlEventValueChanged];
    [rabih addSubview:rabih];

你确定需要它用于 UIWebView 而不是 UITableView 吗? - woz
@woz 是的,我想用这个方法刷新名为rabih的UIWebView。 - David Gölzhäuser
我不确定你想要的效果是什么,但是你不能用JavaScript吗? - woz
@woz 这是针对iOS而不是OSX的。 - David Gölzhäuser
2
只是一条评论:使用“下拉刷新”手势重新加载UIWebView并不是一个很好的用户体验。这些手势通常用于垂直滚动视图,特别是UITableView。 - runmad
8个回答

48
这是如何在UIWebview上使用下拉刷新的方法:
- (void)viewDidLoad
{
   [super viewDidLoad];
   // Do any additional setup after loading the view, typically from a nib.

   // Make webView a delegate to itself

   // I am going to add URL information
   NSString *fullURL = @"http://www.umutcankoseali.com/";
   NSURL *url = [NSURL URLWithString:fullURL];
   NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
   _webView.delegate = (id)self;
   [_webView loadRequest:requestObj];

   UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
   [refreshControl addTarget:self action:@selector(handleRefresh:) forControlEvents:UIControlEventValueChanged];
   [_webView.scrollView addSubview:refreshControl]; //<- this is point to use. Add "scrollView" property.
}

-(void)handleRefresh:(UIRefreshControl *)refresh {
   // Reload my data
   NSString *fullURL = @"http://www.umutcankoseali.com/";
   NSURL *url = [NSURL URLWithString:fullURL];
   NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
   [_webView loadRequest:requestObj];
   [refresh endRefreshing];
}

+1 精妙绝伦的解决方案!完美地运作 - 实际上,它应该能够与任何 UIScrollView 的子类完美地配合使用。 - Sam Spencer
是的!@RazorSharp 也是正确的。 - Umut Koseali

9
在Swift中使用这个方法,假设您想在WebView中实现下拉刷新功能,请尝试以下代码:
override func viewDidLoad() {
    super.viewDidLoad()
    addPullToRefreshToWebView()
}

func addPullToRefreshToWebView(){
    var refreshController:UIRefreshControl = UIRefreshControl()

    refreshController.bounds = CGRectMake(0, 50, refreshController.bounds.size.width, refreshController.bounds.size.height) // Change position of refresh view
    refreshController.addTarget(self, action: Selector("refreshWebView:"), forControlEvents: UIControlEvents.ValueChanged)
    refreshController.attributedTitle = NSAttributedString(string: "Pull down to refresh...")
    YourWebView.scrollView.addSubview(refreshController)

}

func refreshWebView(refresh:UIRefreshControl){
    YourWebView.reload()
    refresh.endRefreshing()
}

在Objective-C中,我使用了以下代码:
- (void)addPullToRefreshToWebView{
    UIColor *whiteColor = [UIColor whiteColor];
    UIRefreshControl *refreshController = [UIRefreshControl new];
    NSString *string = @"Pull down to refresh...";
    NSDictionary *attributes = @{ NSForegroundColorAttributeName : whiteColor };
    NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:string attributes:attributes];
    refreshController.bounds = CGRectMake(0, 0, refreshController.bounds.size.width, refreshController.bounds.size.height);
    refreshController.attributedTitle = attributedString;
    [refreshController addTarget:self action:@selector(refreshWebView:) forControlEvents:UIControlEventValueChanged];
    [refreshController setTintColor:whiteColor];
    [self.webView.scrollView addSubview:refreshController];
}

- (void)refreshWebView:(UIRefreshControl*)refreshController{
    [self.webView reload];
    [refreshController endRefreshing];
}

5

我刚刚很快地将这个代码添加到了我的程序中:

[webserver.scrollView addSubview:refreshControl]

看起来 UIWebView 本身有一个可以附加的 UIScrollView。希望这对您有用。

那么,您能否编辑您的答案来完成问题呢?您是如何更改代码的? - Umut Koseali
-(void)viewDidLoad { [super viewDidLoad]; self.refreshControl = [[UIRefreshControl alloc] init]; [self.refreshControl addTarget:self action:@selector(loadPage) forControlEvents:UIControlEventValueChanged]; [self.webView.scrollView addSubview:self.refreshControl]; }-(void)viewDidLoad { [super viewDidLoad]; self.refreshControl = [[UIRefreshControl alloc] init]; [self.refreshControl addTarget:self action:@selector(loadPage) forControlEvents:UIControlEventValueChanged]; [self.webView.scrollView addSubview:self.refreshControl]; } - William Entriken

3

我实际尝试过这个方法,但是遇到了以下错误。

* 由于未捕获的异常 'NSInternalInconsistencyException' 而终止应用程序,原因是:'UIRefreshControl may only be managed by a UITableViewController'

不过我可以在 UIScrollView 和 UICollectionView 中使用它。


0

我的答案基于 @Zaid Pathan 的回答,但已更新为 Swift 4。

class WebViewController: UIViewController, WKUIDelegate, WKNavigationDelegate {

var refreshController:UIRefreshControl!
var webView: WKWebView!

override func viewDidLoad() {
    super.viewDidLoad()
//Your webView initializing

    webView.scrollView.bounces = true //DONT FORGET IT!!!

    refreshController = UIRefreshControl()

    refreshController.bounds = CGRect(x: 0, y: 50, width: refreshController.bounds.size.width, height: refreshController.bounds.size.height)
    refreshController.addTarget(self, action: #selector(self.refreshWebView(refresh:)) , for: UIControlEvents.valueChanged)
    refreshController.tintColor = #colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
    webView.scrollView.addSubview(refreshController)
}

@objc func refreshWebView(refresh:UIRefreshControl){
    webView.reload()
}

最后,不要忘记停止重新加载:
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    if refreshController.isRefreshing{
        refreshController.endRefreshing()
    }
}

0

目前我不相信这样做是可行的。实际上,你不能将它与任何UITableView一起使用。tableView需要作为UITableViewController的一部分才能被正确地使用。

话虽如此,你可能可以通过手动控制其框架和值,将一个UITableView放在UIWebView上方并使其正常工作。UITableViewController已经通过其refreshControl属性自动更新来完成了这些事情。


我知道这是可能的,因为我知道有一个应用程序可以做到这一点。 - David Gölzhäuser
即使可能可以做到,也不意味着你应该这样做。而且他们可能没有使用UIRefreshControl,只是擅长复制苹果的风格,这在过去很多次都出现过。 - Ryan Poolos

0

看一下CKRefreshControl,你可能可以根据自己的需求进行定制。


0

扩展@umut-can-köseali的答案以在刷新结束时更好地控制UIRefreshControl:

- (void)viewDidLoad {
    [super viewDidLoad];
    _refreshControl = [[UIRefreshControl alloc] init];
    [_refreshControl addTarget:self action:@selector(handleWebViewRefresh:) forControlEvents:UIControlEventValueChanged];
    [self.webView.scrollView addSubview:_refreshControl]; //<- this is point to use. Add "scrollView" property.
}

- (void)webView:(UIWebView *)_webView didFailLoadWithError:(NSError *)error {
    [_refreshControl endRefreshing];
}

- (void)webViewDidFinishLoad:(UIWebView *)_webView {
    NSString *navigatorUrl = _webView.request.URL.absoluteString;
    if( navigatorUrl && ![navigatorUrl isEqualToString:@""]) {
        NSString *host=_webView.request.URL.host;
        NSString *path=_webView.request.URL.path;
        [_refreshControl endRefreshing];
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接