问题
My app shows articles from an RSS feed in a table view then when you select a row, opens a web view controller to show the article. I'm trying to add a loading indicator. If I select a row, the indicator will show briefly and then disappear before the page is fully loaded. Also, if I go back to the table view and select a different row, the loading indicator never shows up. I'm using a custom loading indicator called SVProgressHUD and it works fine elsewhere in the app. I don't think that is the problem though. What am I doing wrong?
Here is my didSelectRowAtIndexPath method in my table view:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[[webViewController webView]loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"about:blank"]]];
[self.navigationController pushViewController:webViewController animated:YES];
// Grab the selected item
RSSItem *entry = [[channel items]objectAtIndex:[indexPath row]];
// Construct a URL with the link string of the item
NSURL *url = [NSURL URLWithString:[entry link]];
// Construct a request object with that URL
NSURLRequest *req = [NSURLRequest requestWithURL:url];
// Load the request into the web view
[[webViewController webView]loadRequest:req];
webViewController.hackyURL = url;
}
The loading indicator is started on this line in viewDidLoad of the WebViewController:
[SVProgressHUD showWithStatus:@"Loading"];
And here is my WebViewController.
#import "WebViewController.h"
#import "TUSafariActivity.h"
#import "SVProgressHUD.h"
@implementation WebViewController
@synthesize webView=webView, hackyURL=hackyURL;
- (void)loadView
{
// Create an instance of UIWebView as large as the screen
CGRect screenFrame = [[UIScreen mainScreen]applicationFrame];
UIWebView *wv = [[UIWebView alloc]initWithFrame:screenFrame];
webView = wv;
NSLog(@"%@",webView.request.URL);
// Tell web view to scale web content to fit within bounds of webview
[wv setScalesPageToFit:YES];
[self setView:wv];
}
- (UIWebView *)webView
{
return (UIWebView *)[self view];
}
- (void) showMenu
{
NSURL *urlToShare = hackyURL;
NSArray *activityItems = @[urlToShare];
TUSafariActivity *activity = [[TUSafariActivity alloc] init];
__block UIActivityViewController *activityVC = [[UIActivityViewController alloc]initWithActivityItems:activityItems applicationActivities:@[activity]];
activityVC.excludedActivityTypes = @[UIActivityTypeAssignToContact, UIActivityTypePostToWeibo, UIActivityTypeSaveToCameraRoll];
[self presentViewController:activityVC animated:YES completion:^{activityVC.excludedActivityTypes = nil; activityVC = nil;}];
}
- (void)toggleBars:(UITapGestureRecognizer *)gesture
{
BOOL barsHidden = self.navigationController.navigationBar.hidden;
if (!barsHidden)
{
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];
[self hideTabBar:self.tabBarController];
}
else if (barsHidden)
{
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationSlide];
[self showTabBar:self.tabBarController];
}
[self.navigationController setNavigationBarHidden:!barsHidden animated:YES];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
[SVProgressHUD showWithStatus:@"Loading"];
UIBarButtonItem *systemAction = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:@selector(showMenu)];
self.navigationItem.rightBarButtonItem = systemAction;
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(toggleBars:)];
[webView addGestureRecognizer:singleTap];
singleTap.delegate = self;
// self.hidesBottomBarWhenPushed = YES;
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
- (void) hideTabBar:(UITabBarController *) tabbarcontroller
{
CGRect screenRect = [[UIScreen mainScreen] bounds];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
float fHeight = screenRect.size.height;
if( UIDeviceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation) )
{
fHeight = screenRect.size.width;
}
for(UIView *view in tabbarcontroller.view.subviews)
{
if([view isKindOfClass:[UITabBar class]])
{
[view setFrame:CGRectMake(view.frame.origin.x, fHeight, view.frame.size.width, view.frame.size.height)];
}
else
{
[view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, fHeight)];
view.backgroundColor = [UIColor blackColor];
}
}
[UIView commitAnimations];
}
- (void) showTabBar:(UITabBarController *) tabbarcontroller
{
CGRect screenRect = [[UIScreen mainScreen] bounds];
float fHeight = screenRect.size.height - 49.0;
if( UIDeviceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation) )
{
fHeight = screenRect.size.width - 49.0;
}
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
for(UIView *view in tabbarcontroller.view.subviews)
{
if([view isKindOfClass:[UITabBar class]])
{
[view setFrame:CGRectMake(view.frame.origin.x, fHeight, view.frame.size.width, view.frame.size.height)];
}
else
{
[view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, fHeight)];
}
}
[UIView commitAnimations];
}
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
//stop the activity indicator when done loading
[SVProgressHUD dismiss];
}
@end
回答1:
You should use the delegate
functions of a webview
see below
-(void)webViewDidStartLoad:(UIWebView *)webView{
//SHOW HUD
}
-(void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{
//KILL HUD
}
-(void)webViewDidFinishLoad:(UIWebView *)webView{
if(!webView.loading){
//KILL HUD
}
}
In webview
normally caching happens, so HUD might not show for long as it will show for the first load.
I hope it will help you.
回答2:
This is fixed. I just had to add
webView.delegate = self;
来源:https://stackoverflow.com/questions/18216806/loading-indicator-on-web-view