hi I want to ask a simple question how I can hide or disable progress bar when UIWebView load, I add ProgressBar as subview of webview . I did it by using this way in the method below, but it can't help me because every site take different time to load because of their content size so kindly tell me how I can hide or remove the ProgressBar when any site load in webview
- (void)makeMyProgressBarMoving {
float actual = [threadProgressView progress];
if (actual < 1) {
threadProgressView.progress = actual + 0.2;
[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:#selector(makeMyProgressBarMoving) userInfo:nil repeats:NO];
}
else
{
threadProgressView.hidden = YES;
threadValueLabel.hidden = YES;
}
}
First add delegate to UIWebView
For adding progress bar :-
Web view delegate method :-
- (void)webViewDidStartLoad:(UIWebView *)webView
{
threadProgressView.hidden = NO;
}
For Removing progress bar :-
Web view delegate method :-
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
threadProgressView.hidden = YES;
}
Hope this helps you
Check your webview is loaded completly or not.
if(!yourWebView.loading)
{
[yourProgress removeFromSuperView];
}
loading
A Boolean value indicating whether the receiver is done loading
content. (read-only) #property(nonatomic, readonly, getter=isLoading) BOOL loading >
Discussion
If YES, the receiver is still loading content; otherwise, NO.
Availability
Available in iOS 2.0 and later.
or
You can implement the webViewDidFinishLoad delegate method of UIWebView.
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
[yourProgress removeFromSuperView];
}
webViewDidFinishLoad:
Sent after a web view finishes loading a frame.
- (void)webViewDidFinishLoad:(UIWebView *)webView
Parameters
webView
The web view has finished loading.
Availability
Available in iOS 2.0 and later.
Refer UIWebViewDelegate,UIWebView for more details
Related
I am using ZBar iPhone SDK in one of my projects (iOS SDK 5.1 ,XCode 4.4.1 and device running iOS 5.5.1). I am using the embedded scanner from the examples provided in the SDk itself.
Now the issue which I am facing is that I successfully scan a bar code and move to another view controller ( using navigation controller). When I come back (pop the second view controller) the scanner i.e the ZBarReaderView doesn't scan the subsequent bar codes , infact the overlay shows a blur image of the scanned barcode and is never able to scan it properly.
This is what all I have implemented . In BarScannerViewController.h I have declared
ZBarReaderView* readerView;
with property
#property (nonatomic , retain) IBOutlet UIImageView* imgvScannedBarCode;
Now this is connected to one of the views in xib.
Finally I use set up the required methods as follows -
- (void)viewDidLoad {
[super viewDidLoad];
// the delegate receives decode results
readerView.readerDelegate = self;
[readerView start];
}
- (void) viewDidAppear: (BOOL) animated {
// run the reader when the view is visible
[activityIndicatorScanning startAnimating];
[readerView start];
}
- (void) viewWillDisappear: (BOOL) animated {
[activityIndicatorScanning stopAnimating];
[readerView stop];
}
With all this set up when I scan any bar code say EAN123 for the first time I get the call back in
- (void) readerView: (ZBarReaderView*) view
didReadSymbols: (ZBarSymbolSet*) syms
fromImage: (UIImage*) img
{
// do something useful with results
ZBarSymbol *symbol = nil;
for(symbol in syms) {
barCodeFound = YES;
break;
}
// EXAMPLE: do something useful with the barcode data
NSLog(#"%#",symbol.data);
}
but on subsequent runs (After I push a view and come back on this screen again) I get blurred view.
Am I missing something here ? Any help/Suggestion/Comments would be helpful.
Here's the code that I use to start (and endlessly restart) the scanner. Interestingly, I note that I never stop the scan, but it works very reliably.
- (void) startScan
{
ZBarReaderViewController *reader = [ZBarReaderViewController new];
reader.readerDelegate = self;
ZBarImageScanner *scanner = reader.scanner;
[scanner setSymbology: ZBAR_I25
config: ZBAR_CFG_ENABLE
to: 0];
// present and release the controller
[self presentViewController:reader animated:YES completion:nil]; // Modal
[reader release];
}
I could solve the Blur issue by reconfiguring the SDK in my project. I followed the embedded scanner example as provided on ZBarSDk. I guess I might have missed some essential settings while configuring it earlier.
Hey guys! I have a tumblr app that I am developing, and I have a button that pushes a modal view that contains a webview and a toolbar on the bottom with refresh, back, forward and done buttons. The back forward and refresh buttons work, however I want to be able to tell if the webview can actually go back/forward and if not, disable the button..I have tried the code below, and the image nor the enable/disable changes.
- (IBAction)refreshPage {
[signUpWebView reload];
}
- (IBAction)goBack {
[signUpWebView goBack];
}
- (IBAction)goForward {
[signUpWebView goForward];
}
-(void)webViewDidFinishLoad:(UIWebView *)webView
{
// Enable or disable back
if ([signUpWebView canGoBack]) {
[backOnePage setEnabled:YES];
backOnePage.image = [UIImage imageNamed:#"backButton"];
} else {
[backOnePage setEnabled:NO];
backOnePage.image = [UIImage imageNamed:#"backButtonDisabled"];
}
// Enable or disable forward
if ([signUpWebView canGoForward]) {
[forwardOnePage setEnabled:YES];
forwardOnePage.image = [UIImage imageNamed:#"forwardButton"];
} else {
[forwardOnePage setEnabled:NO];
forwardOnePage.image = [UIImage imageNamed:#"forwardButtonDisabled"];
}
}
Any recommendations would be greatly appreciated!
I recommend binding the forward and backward button directly to the UIWebview.
Automatically enable and disable like this:
- (void)webViewDidStartLoad:(UIWebView *)mwebView {
backButton.enabled = (webView.canGoBack);
forwardButton.enabled = (webView.canGoForward);
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
backButton.enabled = (webView.canGoBack);
forwardButton.enabled = (webView.canGoForward);
}
When you first initialize your webView, try starting it with a request, like this:
[signUpWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.google.com"]]];
So you're initializing the webView with loadRequest: instead of loadHTMLString:, or something similar.
i have web view in that i am loading pdf file .
pdf file has 2 mb size so it tacking time. i want to add indicator .
for that how can i know my file is loaded in web view ? ...
UIWebViewDelegate
in particular:
- (void)webViewDidFinishLoad:(UIWebView *)webView
James P has the right answer (^'ed), but here is the code to show and hide the indicator.
After you've registered with the UIWebViewDelegate...
- (void)webViewDidStartLoad:(UIWebView *)webView {
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
// Other stuff...
}
And then
- (void)webViewDidFinishLoad:(UIWebView *)webView {
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
// Other stuff...
}
Also you probably want to check for failures and hide the activity indicator there as well...
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
// Other stuff...
}
first Add the delegate "UIWebViewDelegate", then you can use the below methods.
– webView:shouldStartLoadWithRequest:navigationType:
– webViewDidStartLoad:
– webViewDidFinishLoad:
– webView:didFailLoadWithError:
You could pull your PDF down using ASIHTTPRequest, which would let you set up a progress bar showing real progress, and then feed it to your UIWebView once it's downloaded.
EDIT: ASIHTTPRequest is a free third-party library that provides a MUCH improved interface to iOS HTTP client functions. LOTS of code samples and instructions here: http://allseeing-i.com/ASIHTTPRequest/How-to-use
I have an embedded website that has many links but the webview window is fairly small to allow for a larger image above the list to be zoomed in and out. I need the webview to respond to hyperlinks into a new controller view with a second embedded UIWebView if at all possible.
The UIWebView has a delegate wich allows you to respond to certain events, e.g. a request to load new content. Just implement the following in your delegate-class
-(bool) webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
//You might need to set up a interceptLinks-Bool since you don't want to intercept the initial loading of the content
if (self.interceptLinks) {
NSURL *url = request.URL;
//This launches your custom ViewController, replace it with your initialization-code
[YourBrowserViewController openBrowserWithUrl:url];
return NO;
}
//No need to intercept the initial request to fill the WebView
else {
self.interceptLinks = YES;
return YES;
}
}
The webViewDidFinishLoad message seems to be sent each time any object in the page has been loaded. Is there a way to determine that all loading of content is done?
I'm guessing that iframes cause the webViewDidStartLoad / webViewDidFinishLoad pair.
The [webView isLoading] check mentioned as an answer didn't work for me; it returned false even after the first of two webViewDidFinishLoad calls. Instead, I keep track of the loading as follows:
- (void)webViewDidStartLoad:(UIWebView *)webView {
webViewLoads_++;
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
webViewLoads_--;
if (webViewLoads_ > 0) {
return;
}
…
}
- (void)webView:(UIWebView*)webView didFailLoadWithError:(NSError*)error {
webViewLoads_--;
}
(Note this will only work if the start / finished pairs don't come serially, but in my experience so far that hasn't happened.)
Check this one, it will definitely work for you:
- (void)webViewDidFinishLoad:(UIWebView *)webView {
if ([[webView stringByEvaluatingJavaScriptFromString:#"document.readyState"] isEqualToString:#"complete"]) {
// UIWebView object has fully loaded.
}
}
Interesting, I wouldn't have thought it would work like that. Although I'm sure there are other ways to do it (is there a way to extract the URL from the webViewDidFinishLoad message so that you can see which one is the main page finishing loading?), the main thing I can think of is using the estimatedProgress to check the progress of the page and fire off whatever you want to do when it's 100% finished loading, which is what I do in my app. Google "iphone webview estimatedprogress" and click the first link for a guide I wrote on how to do this.
Update:
Please use phopkins' answer below instead of mine! Using private APIs in your apps is a bad idea and you will probably get rejected, and his solution is the right one.
Another way to monitor load progress with less control is to observe the WebViewProgressEstimateChangedNotification, WebViewProgressFinishedNotification, and WebViewProgressStartedNotification notifications. For example, you could observe these notifications to implement a simple progress indicator in your application. You update the progress indicator by invoking the estimatedProgress method to get an estimate of the amount of content that is currently loaded.
from http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/WebKit/Classes/WebView_Class/Reference/Reference.html
You can also use this short Category I wrote that adds blocks into UIWebView and also lets you choose between default UIWebView behavior (getting notified after each object load), or the "expected" behavior (getting notified only when the page has fully loaded).
https://github.com/freak4pc/UIWebView-Blocks
I needed to capture a variable from the page which was not fully loaded yet.
This worked for me:
- (void) webViewDidFinishLoad:(UIWebView *)webView {
NSString *valueID = [webView stringByEvaluatingJavaScriptFromString:#"document.valueID;"];
if([valueID isEqualToString:#""]){
[webView reload];
return;
}
//page loaded
}
All of the options did not really work for my use case. I used phopkins example slightly modified. I found that if the HTML loaded into the webview contained an image that would be a separate request that happened serially so we have to account for that and I did that with a timer. Not the best solution but it seems to work.:
- (void)webViewActuallyFinished {
_webViewLoads--;
if (_webViewLoads > 0) {
return;
}
//Actually done loading
}
- (void)webViewDidStartLoad:(UIWebView *)webView {
_webViewLoads++;
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
[NSTimer scheduledTimerWithTimeInterval:2 target:self selector:#selector(webViewActuallyFinished) userInfo:nil repeats:NO];
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
_webViewLoads--;
}
hi it may be a bit far back already but i hope this helps.
i just used a notification when it enters the webViewDidFinishLoad method so that i can capture one instance of the method and then i'll detect the notification and do my logic from there.
hope this helps. it does not capture the last called instance of the webViewDidFinishLoad method, but allows you to do something once it has been called and not be repeated calls to that particular method (eg. showing a button) too.
*********EDIT*********
i did a test and managed to test it out. it actually works and the method called from the notification will be called after the full page has been loaded.
alternatively, i think you can do a counter on the delegate method webViewDidStartLoad and also on webViewDidFinishLoad to make sure that they are the same before you run your codes. this though, is an ugly hack as we will never know how many times it will be called unless like me, you are loading a html feed and can add a JavaScript to check how many elements there are on the page that you are loading. i'm just sharing some of the methods i have tried to solve this. hope it helps.
feedback is encouraged. thanks!
Here's what I use to show a spinner while DOM loads, built on top of #Vinod's answer.
Note that between webViewDidStartLoad and webViewDidFinishLoad the readyState is completed from the previous request (if any), that's why the polling should begin after webViewDidFinishLoad.
readyState possible values are loading, interactive or completed (and maybe nil ?)
- (void)webViewDidStartLoad:(UIWebView *)webView {
[self spinnerOn];
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
[self startDOMCompletionPolling];
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
[self startDOMCompletionPolling];
}
- (void)startDOMCompletionPolling {
if (self.domCompletionListener) {
[self.domCompletionListener invalidate];
}
self.domCompletionListener = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:#selector(checkDOMCompletion) userInfo:nil repeats:YES];
}
- (void)checkDOMCompletion {
NSString *readyState = [self.webView stringByEvaluatingJavaScriptFromString:#"document.readyState"];
if (readyState != nil) {
if (readyState.length > 0) {
if ([readyState isEqualToString:#"loading"]) { //keep polling
return;
}
}
}
//'completed', 'interactive', nil, others -> hide spinner
[self.domCompletionListener invalidate];
[self spinnerOff];
}
The way I do it is this:
- (void)webViewDidFinishLoad:(UIWebView *)webview {
if (webview.loading)
return;
// now really done loading code goes next
[logic]
}