I am using the below to add a ProgressView while the UIWebView is loading and dismissing it when it's done.
The problem is the UIWebView is started twice and also the ProgressView, So when the page is done loading only one ProgressView is dismissed and the other one doesn't.
ViewController.h
#import <UIKit/UIKit.h>
#interface DirectionViewController : UIViewController <UIWebViewDelegate>
#property (weak, nonatomic) IBOutlet UIWebView *directionWebView;
#end
ViewController.m
#interface ViewController ()
#property UIColor *yellowColor;
#property MRProgressOverlayView *progressView;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.yellowColor =
[UIColor colorWithRed:244.0f/255.0f
green:208.0f/255.0f
blue:63.0f/255.0f
alpha:1.0f];
self.directionWebView.delegate = self;
NSString *urlMap = [NSString stringWithFormat:#"%#%f,%f&zoom=14", #"http://maps.google.com/maps?q=", self.coordLat, self.coordLong];
NSURL *url = [NSURL URLWithString:urlMap];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
[self.directionWebView loadRequest:urlRequest];
}
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSLog(#"WebView start loading...");
self.progressView = [MRProgressOverlayView new];
self.progressView.mode = MRProgressOverlayViewModeIndeterminateSmall;
[self.view.window addSubview:self.progressView];
[self.progressView setTintColor:self.yellowColor];
[self.progressView setTitleLabelText:#"Loading ..."];
[self.progressView show:YES];
return YES;
}
-(void)webViewDidFinishLoad:(UIWebView *)webView
{
[self.progressView dismiss:YES];
}
#end
Dont know why it is calling twice but you can do this.
if(!self.progressView){
self.progressView = [MRProgressOverlayView new];
self.progressView.mode = MRProgressOverlayViewModeIndeterminateSmall;
[self.view.window addSubview:self.progressView];
[self.progressView setTintColor:self.yellowColor];
[self.progressView setTitleLabelText:#"Loading ..."];
[self.progressView show:YES];
}
-(void)webViewDidFinishLoad:(UIWebView *)webView
{
[self.progressView dismiss:YES];
self.progressView = nil;
}
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
it may be triggered more than once, e.g redirects, iframe loading and so on. It's very inconvenient to initialise objects here.
Use Lazy Initialization design pattern for it
- (MRProgressOverlayView *)progressView {
if (_progressView) {
_progressView = [... alloc] init];
// ... setup your progressView
}
return _progressView;
}
btw, you forgot about error handling:
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
// You need to stop loading indicator here, right?!
}
Second thing is - (maybe for you case it's not a big deal) but usually it's tricky to exactly determine when UIWebView stopped loading (all the resources loaded, AJAX requests and so on)
Personally I'm using something like code below to manage activity indicator start/stop behaviour for UIWebView
#pragma mark UIWebViewDelegate
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType
{
NSLog(#"Webview (%p) starting to load URL: %#", self, request.URL);
self.URL = request.URL;
return YES;
}
- (void)webViewDidStartLoad:(UIWebView *)webView
{
[self.spinner startAnimating];
self.webViewLoadingCount++;
}
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
self.webViewLoadingCount--;
if (self.webViewLoadingCount > 0) return;
[self.spinner stopAnimating];
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
self.webViewLoadingCount--;
[self.spinner stopAnimating];
// Ignore NSURLErrorDomain error (-999).
if (error.code == NSURLErrorCancelled) return;
// Ignore "Frame Load Interrupted" errors
if (error.code == 102 && [error.domain isEqual:#"WebKitErrorDomain"]) return;
NSLog(#"WebView (%p) experienced an error: %#.", self, [error localizedDescription]);
}
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
This delegate method can be called multiple times (in case of redirection for example). So I would recommend to move your Progress view init code to viewDidLoad method.
- (void)viewDidLoad {
[super viewDidLoad];
//...
self.progressView = [MRProgressOverlayView new];
self.progressView.mode = MRProgressOverlayViewModeIndeterminateSmall;
[self.view.window addSubview:self.progressView];
[self.progressView setTintColor:self.yellowColor];
[self.progressView setTitleLabelText:#"Loading ..."];
}
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSLog(#"WebView start loading...");
[self.progressView show:YES];
return YES;
}
-(void)webViewDidFinishLoad:(UIWebView *)webView {
[self.progressView dismiss:YES];
}
Related
My cordova library was old and had to update it because of iOS11. I have updated it to latest version 4.4.0. CDVViewController is totally different now which enables webviewEngine that takes UIWebview or WKWebview. How do I initiate Cordova webview in my native app. Previously, I loaded it like this -
- (void) viewDidLoad {
[super viewDidLoad];
CDVViewController *viewController = [CDVViewController new];
viewController.wwwFolderName = #"www";
viewController.startPage = #"blank.html";
viewController.view.frame = self.webView.frame;
[self.webView removeFromSuperview];
self.webView = nil;
[self.view addSubview:viewController.view];
self.webView = viewController.webView;
viewController.webView.delegate = self;
self.cordovaWebViewController = viewController;
self.webView.scalesPageToFit = YES;
if (self.url)
[self.webView loadRequest: [NSURLRequest requestWithURL: self.url]];
}
And used webview delegates as
#pragma mark Webview Delegate
- (void) webViewDidStartLoad: (UIWebView *) webViewLocal {
[self.spinner startAnimating];
[self.cordovaWebViewController webViewDidStartLoad:webViewLocal];
}
- (void) webViewDidFinishLoad: (UIWebView *) webViewLocal {
[self.spinner stopAnimating];
[self.cordovaWebViewController webViewDidFinishLoad:webViewLocal];
}
- (void) webView: (UIWebView *) webView didFailLoadWithError: (NSError *) error {
[self.spinner stopAnimating];
}
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if (navigationType == UIWebViewNavigationTypeLinkClicked) {
if ([request.URL.absoluteString hasSuffix: #"link_restart_movie_file"]) {
[self loadItem];
return NO;
}
[self.webView loadRequest: request];
return NO;
}
[self.cordovaWebViewController webView:self.webView shouldStartLoadWithRequest:request navigationType:navigationType];
return YES;
}
How do I use WebviewEngine to load in my viewcontroller? Is there any tutorial, that explains the usage of CDVViewController? Please help! Thanks!
I have a main UIWebView and I am trying to open any URL using SVWebViewController. My code can be seen bellow.
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if (navigationType == UIWebViewNavigationTypeLinkClicked ) {
SVModalWebViewController *webViewController = [[SVModalWebViewController alloc] initWithAddress:#"http://google.com"];
[self presentViewController:webViewController animated:YES completion:NULL];
return NO;
}
return YES;
}
It seems like SVWebViewController has an initWithAddress parameter. I want to know if I can pass the requested URL in that parameter.
Thank you in advance.
Found a way out of this. It seems like I could work with
initWithURLRequest:(NSURLRequest *)request
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if (navigationType == UIWebViewNavigationTypeLinkClicked ) {
SVModalWebViewController *webViewController = [[SVModalWebViewController alloc] initWithURLRequest:(NSURLRequest *)request];
[self presentViewController:webViewController animated:YES completion:NULL];
return NO;
}
return YES;
}
I am making an app for iOS, use UIwebview to load my website in the app. I want all links (besides my website) open in Safari. Read many articles and tried many different suggestion still can't make it.
I am not familiar in coding, use Xcode 6.3.2
Here is my code of ViewController.m:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *fullURL = #"http://www.mywebsite.com";
NSURL *url = [NSURL URLWithString:fullURL];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[_viewWeb loadRequest:requestObj];
}
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
// Check if this was a click event and then some other criteria for determining if you want to launch Safari.
if (navigationType == UIWebViewNavigationTypeLinkClicked
&& [ [ request.URL scheme ] isEqualToString: #"http" ] ) {
[[UIApplication sharedApplication] openURL:request.URL];
// Return false to indicate to the UIWebView to not navigate to the linked target
return false;
}
// Return true so that the UIWebView loads the link target
return true;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
please help
Update your method
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
in something like:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSString *requestURL = [[request URL] absoluteString];
if ([requestURL rangeOfString:#"mydomain.com"].location != NSNotFound) {
[[UIApplication sharedApplication] openURL:[request URL]];
return NO;
}
return YES;
}
How can i set the delegate method of a UIWebView in a class?
when i do it, the app carsh.
#interface MineWebViewHandle : NSObject<UIWebViewDelegate>
#end
//.m
#implementation MineWebViewHandle
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSString *urlString = [[request URL] absoluteString];
return YES;
}
- (void)webViewDidStartLoad:(UIWebView *)webView
{
NSLog(#"did start load");
}
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
NSLog(#"did finished ");
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
NSLog(#"webview error:%#",[error localizedDescription]);
}
i use it:
self.m_pWebView = [[UIWebView alloc] initWithFrame:CGRectZero];
MineWebViewHandle *handle = [[MineWebViewHandle alloc]init];
self.m_pWebView.delegate = handle;
self.m_pWebView.backgroundColor = [UIColor whiteColor];
[self.view addSubview:self.m_pWebView];
how do i use it rightly?
Your delegate look like is create in viewDidLoad,and in the end of this it´s release (put to nil).
You need create a property called: MineWebViewHandle *handle.
in your viewController.h add:
#property (nonatomic,strong)MineWebViewHandle *handle;
and change in your code:
self.handle = [[MineWebViewHandle alloc]init];
self.m_pWebView.delegate = self. handle;
And it´s good idea your webView will have dimensions, change this:
self.m_pWebView = [[UIWebView alloc] initWithFrame:self.view.frame];
Webview is the UIView, Not a controler.
Please remove the NSObject and add the UIview
#interface MineWebViewHandle : UIView
#end
I want to create an iPhone WebView App. But there is a problem, if I click on some buttons, it opens the normal and not the mobile version.
I did create the same WebView app on Android and there I solve the problem with this code
webView.setWebViewClient(new WebViewClient(){
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url)
{
if(!url.toLowerCase().contains("http://www.example.com/"))
{
webView.loadUrl(url + "?mt=1");
return true;
}
return false;
}
});
How can I do this on xcode?
Thank you very much
Best wishes
Dominik
You can do the same using the UIWebViewDelegate protocol.
I think you can achieve the required result by changing the NSURLRequest within the delegate function
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request.......
//delegate methods
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
//use NSURLRequest object request , to manage the request.
//use NSURLRequest object request , to manage the request.
NSURL *urL=request.URL;
NSString *urlStr=[urL absoluteString];
NSLog(#"URLL %#",urlStr);
if([urlStr isEqualToString:#"http://www.google.com/"]){
urL=[NSURL URLWithString:#"http://www.yahoo.com"];
request=[request initWithURL:urL];
[webView loadRequest:request];
}
return YES;
}
- (void)webViewDidStartLoad:(UIWebView *)webView
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
//start of request
}
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
//finished loading
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
//error
}
This will work for sure. I am using above code to load www.yahoo.com when www.google.com is requested.