I'm making a WKWebView app, and I'd like to display a button that when clicked will take me to the homepage of my website. The WebView takes up the whole screen, and when I place a button in the Main.Storyboard file it doesn't show up (I think it's because the webview overlaps it or something).
Here's my ViewController.m
//
// ViewController.m
// FLWebView
//
// Created by Steve Richey on 11/21/14.
// Copyright (c) 2014 Float Mobile Learning. Shared under an MIT license. See license.md for details.
//
#import "ViewController.h"
// Required for calls to UIWebView and WKWebView to "see" our categories
#import "UIWebView+FLUIWebView.h"
#import "WKWebView+FLWKWebView.h"
#interface ViewController ()
#end
#implementation ViewController
/*
* Called when the view has completed loading. Time to set up our WebView!
*/
- (void) viewDidLoad {
[super viewDidLoad];
// Check if WKWebView is available
// If it is present, create a WKWebView. If not, create a UIWebView.
if (NSClassFromString(#"WKWebView")) {
_webView = [[WKWebView alloc] initWithFrame: [[self view] bounds]];
} else {
_webView = [[UIWebView alloc] initWithFrame: [[self view] bounds]];
}
// Add the webView to the current view.
[[self view] addSubview: [self webView]];
// Assign this view controller as the delegate view.
// The delegate methods are below, and include methods for UIWebViewDelegate, WKNavigationDelegate, and WKUIDelegate
[[self webView] setDelegateViews: self];
// Ensure that everything will resize on device rotate.
[[self webView] setAutoresizingMask: UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
[[self view] setAutoresizingMask: UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
// Just to show *something* on load, we go to our favorite site.
[[self webView] loadRequestFromString:#"http://LiftedFeed.com/"];
}
/*
* Enable rotating the view when the device rotates.
*/
- (BOOL) shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation) toInterfaceOrientation
{
return YES;
}
/*
* This more or less ensures that the status bar is hidden for this view.
* We also set UIStatusBarHidden to true in the Info.plist file.
* We hide the status bar so we can use the full screen height without worrying about an offset for the status bar.
*/
- (BOOL) prefersStatusBarHidden
{
return YES;
}
#pragma mark - UIWebView Delegate Methods
/*
* Called on iOS devices that do not have WKWebView when the UIWebView requests to start loading a URL request.
* Note that it just calls shouldStartDecidePolicy, which is a shared delegate method.
* Returning YES here would allow the request to complete, returning NO would stop it.
*/
- (BOOL) webView: (UIWebView *) webView shouldStartLoadWithRequest: (NSURLRequest *) request navigationType: (UIWebViewNavigationType) navigationType
{
return [self shouldStartDecidePolicy: request];
}
/*
* Called on iOS devices that do not have WKWebView when the UIWebView starts loading a URL request.
* Note that it just calls didStartNavigation, which is a shared delegate method.
*/
- (void) webViewDidStartLoad: (UIWebView *) webView
{
[self didStartNavigation];
}
/*
* Called on iOS devices that do not have WKWebView when a URL request load failed.
* Note that it just calls failLoadOrNavigation, which is a shared delegate method.
*/
- (void) webView: (UIWebView *) webView didFailLoadWithError: (NSError *) error
{
[self failLoadOrNavigation: [webView request] withError: error];
}
/*
* Called on iOS devices that do not have WKWebView when the UIWebView finishes loading a URL request.
* Note that it just calls finishLoadOrNavigation, which is a shared delegate method.
*/
- (void) webViewDidFinishLoad: (UIWebView *) webView
{
[self finishLoadOrNavigation: [webView request]];
}
#pragma mark - WKWebView Delegate Methods
/*
* Called on iOS devices that have WKWebView when the web view wants to start navigation.
* Note that it calls shouldStartDecidePolicy, which is a shared delegate method,
* but it's essentially passing the result of that method into decisionHandler, which is a block.
*/
- (void) webView: (WKWebView *) webView decidePolicyForNavigationAction: (WKNavigationAction *) navigationAction decisionHandler: (void (^)(WKNavigationActionPolicy)) decisionHandler
{
decisionHandler([self shouldStartDecidePolicy: [navigationAction request]]);
}
/*
* Called on iOS devices that have WKWebView when the web view starts loading a URL request.
* Note that it just calls didStartNavigation, which is a shared delegate method.
*/
- (void) webView: (WKWebView *) webView didStartProvisionalNavigation: (WKNavigation *) navigation
{
[self didStartNavigation];
}
/*
* Called on iOS devices that have WKWebView when the web view fails to load a URL request.
* Note that it just calls failLoadOrNavigation, which is a shared delegate method,
* but it has to retrieve the active request from the web view as WKNavigation doesn't contain a reference to it.
*/
- (void) webView:(WKWebView *) webView didFailProvisionalNavigation: (WKNavigation *) navigation withError: (NSError *) error
{
[self failLoadOrNavigation: [webView request] withError: error];
}
/*
* Called on iOS devices that have WKWebView when the web view begins loading a URL request.
* This could call some sort of shared delegate method, but is unused currently.
*/
- (void) webView: (WKWebView *) webView didCommitNavigation: (WKNavigation *) navigation
{
// do nothing
}
/*
* Called on iOS devices that have WKWebView when the web view fails to load a URL request.
* Note that it just calls failLoadOrNavigation, which is a shared delegate method.
*/
- (void) webView: (WKWebView *) webView didFailNavigation: (WKNavigation *) navigation withError: (NSError *) error
{
[self failLoadOrNavigation: [webView request] withError: error];
}
/*
* Called on iOS devices that have WKWebView when the web view finishes loading a URL request.
* Note that it just calls finishLoadOrNavigation, which is a shared delegate method.
*/
- (void) webView: (WKWebView *) webView didFinishNavigation: (WKNavigation *) navigation
{
[self finishLoadOrNavigation: [webView request]];
}
#pragma mark - Shared Delegate Methods
/*
* This is called whenever the web view wants to navigate.
*/
- (BOOL) shouldStartDecidePolicy: (NSURLRequest *) request
{
// Determine whether or not navigation should be allowed.
// Return YES if it should, NO if not.
return YES;
}
/*
* This is called whenever the web view has started navigating.
*/
- (void) didStartNavigation
{
// Update things like loading indicators here.
}
/*
* This is called when navigation failed.
*/
- (void) failLoadOrNavigation: (NSURLRequest *) request withError: (NSError *) error
{
// Notify the user that navigation failed, provide information on the error, and so on.
}
/*
* This is called when navigation succeeds and is complete.
*/
- (void) finishLoadOrNavigation: (NSURLRequest *) request
{
// Remove the loading indicator, maybe update the navigation bar's title if you have one.
}
#end
Related
I've implemented a view controller which is displaying a WKWebView. The web view displays certain pages containing links with a tags, e. g.:
<a id="dien10000513721" href="/ge/tr/issue.html" class="dien">Issue</a>
I would like to add a preview to these links by activating 3d-Touch in the web view, but the delegate method webView:shouldPreviewElement: is never called, when I run my app on a iPhone 7 with iOS 11 and doing a force touch on that link.
When I've created my web view and set the necessary properties with
theWebView.navigationDelegate = self;
theWebView.UIDelegate = self;
theWebView.allowsLinkPreview = YES; // Setting this to NO doesn't help
self.webView = theWebView;
The three delegate methods for previewing are implemented as dummies:
- (BOOL)webView:(WKWebView *)inWebView shouldPreviewElement:(WKPreviewElementInfo *)inElementInfo {
NSLog(#"url = %#", inElementInfo.linkURL);
return NO;
}
- (UIViewController *)webView:(WKWebView *)inWebView previewingViewControllerForElement:(WKPreviewElementInfo *)inElementInfo defaultActions:(NSArray<id<WKPreviewActionItem>> *)inPreviewActions {
return nil;
}
- (void)webView:(WKWebView *)webView commitPreviewingViewController:(UIViewController *)previewingViewController {
NSLog(#"");
}
Do I still have to perform any important configuration steps? What else could prevent the execution of 3D touch events?
I m trying to log an error when a page component loaded in a WKWebView fail, but didFailProvisionalNavigation is not called.
I removed a css file from my page to test with it, but no result.
When I load the page on Google Chrome I can find the missing file
The WKWebView is initialised as:
#interface MyWebView : UIViewController <WKNavigationDelegate>
#property(strong,nonatomic) WKWebView *loginWebView;
#end
The .m file
#implementation MyWebView
- (void) initWebView {
// Set and Load the WebView
self.webView = [[WKWebView alloc] initWithFrame:self.view.frame];
self.webView.navigationDelegate = self;
[self.webView loadRequest:request];
[self.view addSubview:self.webView];
}
Then I implemented the methods bellow:
webView:decidePolicyForNavigationAction:decisionHandler:
webView:didStartProvisionalNavigation:
webView:didFinishNavigation:
webView:didFailNavigation:withError:
webView:didFailProvisionalNavigation:withError:
The first three methods get called, but neither didFailNavigation nor didFailProvisionalNavigation are called
By looking at the documentation for didFailProvisionalNavigation we have
Called when an error occurs while the web view is loading content.
Well, a content has failed (css file) and the method is not called, how can I do this?
PS : I also tried using UIWebView!
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{
NSInteger statusCode = ((NSHTTPURLResponse *)navigationResponse.response).statusCode;
NSLog(#"statusCode:%ld", statusCode);
if (statusCode/100 == 4 || statusCode/100 == 5) {
NSLog(#"webview error:%#", navigationResponse.response);
}
decisionHandler(WKNavigationResponsePolicyAllow);
}
this works!
I have implemented a browser in my application by using UIWebView, by default I'm loading google page in my browser.
When I search something in the google page ,the UIWebViewDelegate's webView:shouldStartLoadWithRequest:navigationType: method is called.
The problem is when I tap on the back button from this search page no delegates are getting called, so I am having a problem disabling my back button.
This problem happens only in an iPad application not in an iPhone application.
This code may help u...
A UIWebView is a UIView that can load a web page while remaining in the user's application.
Navigation to other webpages is allowed through the use of imbedded links in a web page itself. Forward and backward navigation through history can be set up with instance methods goForward and goBack, but the programmer must supply the buttons.
The following example uses a UIWebView, and
1) adds forward and backward buttons. The buttons are enabled and highlighted using UIWebViewDelegate optional methods webViewDidStartLoad: and webViewDidFinishLoad:
2) adds a UIActivityIndicatorView which displays while the web page is loading
In the .h file for the WebViewController :
Declare the UIWebView, Optionally : add buttons to control moving forward and backward through browsing history and IBActions for pressing the buttons, Optionally again : add a UIActivityIndicatorView.
#interface WebViewController : UIViewController <UIWebViewDelegate>
{
UIWebView *webView;
UIButton *back;
UIButton *forward;
UIActivityIndicatorView *activityIndicator;
}
#property(nonatomic,retain)IBOutlet UIWebView *webView;
#property(nonatomic,retain)IBOutlet UIButton *back;
#property(nonatomic,retain)IBOutlet UIButton *forward;
#property(nonatomic,retain)IBOutlet UIActivityIndicatorView *activityIndicator;
-(IBAction)backButtonPressed: (id)sender;
-(IBAction)forwardButtonPressed: (id)sender;
#end
//In the .m file for the WebViewController
#implementation WebViewController
#synthesize webView;
#synthesize back;
#synthesize forward;
#synthesize activityIndicator;
//method for going backwards in the webpage history
-(IBAction)backButtonPressed:(id)sender {
[webView goBack];
}
//method for going forward in the webpage history
-(IBAction)forwardButtonPressed:(id)sender
{
[webView goForward];
}
//programmer defined method to load the webpage
-(void)startWebViewLoad
{
//NSString *urlAddress = #"http://www.google.com";
NSString *urlAddress = #"http://cagt.bu.edu/page/IPhone-summer2010-wiki_problemsandsolutions";
//Create a URL object.
NSURL *url = [NSURL URLWithString:urlAddress];
//URL Requst Object
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
//Load the request in the UIWebView.
[webView loadRequest:requestObj];
}
// acivityIndicator is set up here
- (void)viewDidLoad
{
//start an animator symbol for the webpage loading to follow
UIActivityIndicatorView *progressWheel = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
//makes activity indicator disappear when it is stopped
progressWheel.hidesWhenStopped = YES;
//used to locate position of activity indicator
progressWheel.center = CGPointMake(160, 160);
self.activityIndicator = progressWheel;
[self.view addSubview: self.activityIndicator];
[self.activityIndicator startAnimating];
[progressWheel release];
[super viewDidLoad];
//call another method to do the webpage loading
[self performSelector:#selector(startWebViewLoad) withObject:nil afterDelay:0];
}
- (void)dealloc
{
[webView release];
[back release];
[forward release];
[activityIndicator release];
[super dealloc];
}
#pragma mark UIWebViewDelegate methods
//only used here to enable or disable the back and forward buttons
- (void)webViewDidStartLoad:(UIWebView *)thisWebView
{
back.enabled = NO;
forward.enabled = NO;
}
- (void)webViewDidFinishLoad:(UIWebView *)thisWebView
{
//stop the activity indicator when done loading
[self.activityIndicator stopAnimating];
//canGoBack and canGoForward are properties which indicate if there is
//any forward or backward history
if(thisWebView.canGoBack == YES)
{
back.enabled = YES;
back.highlighted = YES;
}
if(thisWebView.canGoForward == YES)
{
forward.enabled = YES;
forward.highlighted = YES;
}
}
#end
/*****************************/
//In viewDidLoad for the class which adds the WebViewController:
WebViewController *ourWebVC = [[WebViewController alloc] initWithNibName:#"WebViewController" bundle:nil];
ourWebVC.title = #"WebView";
[self.view addSubview:ourWebVC];
//release ourWebVC somewhere else
In your case ,You have to ignore/avoid "caching data". Following lines of code may help.
NSURLRequest *requestObj = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.google.com"] cachePolicy: NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:10.0];
[webView loadRequest:requestObj];
Can we load a new url in webview with animation when it loads effect ??
i.e. I want to give my webview an animation when it loads a new url or any link clicked on the opened website in webview.
I want to give pushviewController type animation (right to left movement of screen ) with back button on my webview to go back (left to right movement of webView view) when user taps on link / loads a new url.
Yes.
You can stack a view in - (void)webViewDidStartLoad:(UIWebView *)webView and close it with - (void)webViewDidFinishLoad:(UIWebView *)webView
e.g.,
WebViewController.h
#interface WebViewController : UIViewController<UIWebViewDelegate> {
IBOutlet UIWebView *webView;
}
WebViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
webView.delegate = self;
}
- (void)webViewDidStartLoad:(UIWebView *)webView {
[self.navigationController pushViewController:someViewController animated:YES];
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
[self.navigationController popViewControllerAnimated:YES];
}
When ever a new URL is loading into UIWebView,it's
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
//Code for animating view .
//Code for back button.
}
delegate method will be called .
So do the stuff required for you inside this delegate method.
I've using shouldStartLoadWithRequest very successfully in one of my programs, but the whole project was a proof of concept and scruffy and I'm starting afresh with a new project.
However shouldStartLoadWithReqest is no longer being invoked for me but I can't see where the important difference between the two projects is (however one difference is the first is using .nibs, in the 2nd I'm not using them).
To get things started I'm using a controller with the UIWebView as its view:
#interface IMSRootController : UIViewController <UIWebViewDelegate> {
UIWebView* webView;
}
(webView is declared as a #property and #synthesized)
- (void)loadView {
[super loadView];
webView = [[UIWebView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
self.view = webView;
[webView release]; }
- (void)viewDidLoad {
[super viewDidLoad];
[[self navigationController] setNavigationBarHidden:YES animated:NO];
[self displayPage]; }
-(void) displayPage { ... [webView loadHTMLString:self.htmlString baseURL:baseURL]; }
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
...
What's wrong?
Thanks
Your object is not being set as a delegate of the UIWebView object, hence you will not receive any delegate messages. At some point, either in loadView or even displayPage (but before the call to loadHTMLString:baseURL:), do:
webView.delegate = self;