Introduction
I'm designing a historical application.I want to add multiple HTML files into
WebKit View. I don't have any idea how to do this.
Example
When I click to "Button 1" webkit loads "file1.html". I didn't write anything about code I am quite confused. Any help would be appreciated.
Well, there is a lot of ways to do it but I'm gonna give an example for easiest one. Just create a method for loading .html file and invoke or call it under action button.
For example :
import UIKit
import WebKit
class ExampleController: UIViewController {
#IBOutlet weak var myButton: UIButton!
#IBOutlet weak var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
webView.navigationDelegate = self
}
#IBAction func firstButtonPressed(_ sender: UIButton) {
// Here you can call your method to load html page.
loadPage(pageName: "privacy_policy")
}
#IBAction func secondButtonPressed(_ sender: UIButton) {
// Here you can call different html page.
loadPage(pageName: "terms")
}
// With this method you can call html page by it name (as parameter)
fileprivate func loadPage(pageName: String) {
let url = Bundle.main.url(forResource: pageName, withExtension: "html")
// file url is ready lets to add it as parameter for webView.
webView.loadFileURL(url!, allowingReadAccessTo: url!)
}
}
extension AboutAppController: WKNavigationDelegate {
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
// Here you can add start your animations (like activity indicator)
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
// And here finish your animations.
}
}
Related
I'm setting up an app, where the WKWebView object is created in one class, and then passed to another class for handling, but when I use didFinish navigation in the second class, it never gets called.
I have added the WKNavigationDelegate protocol, and set navigationDelegate = self
class one: UIViewController {
var webView: WKWebView = WKWebView();
override func viewDidLoad(){
var second = Second()
second.web = webView;
second.test()
}
}
class second: NSObject, WKNavigationDelegate {
var web: WKWebView? = nil;
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
print("Test")
}
func test(){
self.web!.load(URLRequest(url: URL(string: "https://google.com")!))
}
}
I never see the "Test" message.
Make it an instance var to retain the object so delegate to be called
var second = Second() /// << here
override func viewDidLoad(){
super.viewDidLoad()
......
}
func test(){
self.web!.navigationDelegate = self
self.web!.load(URLRequest(url: URL(string: "https://google.com")!))
}
import UIKit
import WebKit
class WKWebViewController: UIViewController, WKNavigationDelegate {
#IBOutlet weak var webWK: WKWebView!
#IBOutlet weak var activityIndi: UIActivityIndicatorView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
webWK.navigationDelegate = self
let appStoreURL = URL(string: "https://google.com")
webWK.load(URLRequest(url: appStoreURL!))
}
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
activityIndi.startAnimating()
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
activityIndi.stopAnimating()
}
}
I want to display progress while the WebView is loading and dismiss it when the WebView finishes loading.
I tried this code:
import UIKit
import WebKit
import SVProgressHUD
class ViewController: UIViewController, UIWebViewDelegate {
#IBOutlet var WebView1: WKWebView!
#IBOutlet var WebView2: WKWebView!
let YouTubeURL = URL (string: "https://www.youtube.com/")
#IBAction func YTButtonAction(_ sender: Any) {
let YTRequest = URLRequest(url: YouTubeURL!)
WebView1.load(YTRequest)
if WebView1.isLoading {
SVProgressHUD.show()
}
func webViewDidFinishLoad(WebView1 : UIWebView) {
SVProgressHUD.dismiss()
}
}
}
But it doesn't work.
The progress continue rotating.
Anybody knows how to solve this problem?
Three fatal issues:
You have to set the delegate
WebView1.delegate = self
The signature of the delegate method is wrong
func webViewDidFinishLoad(_ webView: UIWebView)
The delegate method must be on the top level of the class.
I think there is a fourth fatal issue: I doubt that WKWebView conforms to UIWebViewDelegate at all. I suppose you have to adopt WKNavigationDelegate and implement webView(:didFinish:) instead.
And please conform to the Swift naming convention that variable and function / method names start with a lowercase letter.
The answer :
I changed
UIWebViewDelegate to WKNavigationDelegate
WebView1.delegate = self to WebView1. navigationDelegate = self
The name of the WKWebView property is navigationDelegat
func webViewDidFinishLoad(WebView1 : UIWebView) to
func webView(_ webView: WKWebView,
didFinish navigation: WKNavigation!)
I would like to load a web page then be able to retrieve the current web page after the user has logged in and been redirected. I have achieved the loading of a webpage but am unable to retrieve the URL after the user has moved to a new page. The current code that I have is:
#IBOutlet weak var webView: UIWebView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
needlogin()
}
func needlogin(){
let url = URL(string: "https://www.instagram.com/oauth/authorize/?client_id="+clientid+"&redirect_uri="+redirecturl+"&response_type=token&scope=likes+comments+public_content+follower_list+relationships")
let urlrequest = URLRequest(url: url!)
webView.loadRequest(urlrequest)
self.webView.delegate = self
}
func webViewDidFinishLoad(_ webView: UIWebView){
}
The problem I have is with self.webView.delegate = self . I get the error message :
Cannot assign value of type 'ViewController' to type
'UIWebViewDelegate?'
Furthermore I have no clue how to retrieve the URL at all and would appreciate your help.
You would need to conform to UIWebviewDelegate protocol. So you would need to do something like
class ViewController: UIViewController, UIWebViewDelegate {
}
at the top of your class definition.
To retrieve the URL after the webview has finished loading, within your webViewDidFinishLoad method, you would need to do something like webView.request.URL.
Disclaimer: You should be using WKWebview rather than UIWebview for iOS + applications. The way to do it would be something like this for your example:
import UIKit
import WebKit
class WebviewController: UIViewController, WKNavigationDelegate {
var wkWebview : WKWebView?
override func viewDidLoad() {
super.viewDidLoad()
needsLogin()
}
func needsLogin() {
wkWebview = WKWebView.init(frame: self.view.bounds)
wkWebview?.navigationDelegate = self
self.view.addSubview(wkWebview!)
let url = URL(string: "https://www.instagram.com/oauth/authorize/? client_id="+clientid+"&redirect_uri="+redirecturl+"&response_type=token&scope=likes+comments+public_content+follower_list+relationships")
let urlRequest: URLRequest = URLRequest.init(url: url!)
wkWebview?.load(urlRequest)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
public func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
print("\(error.localizedDescription)")
}
public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
// This is the URL you need.
let url = webView.url
}
}
I want to load HTML pages using WkWebView and I want to show the page just after it's finished loading. As long as it's loading I would like to show an activity indicator on an empty View.
I create two view a loadingView and a wkWebView. While the page is loading I add to VC as subview the loadingView and after I want to remove loadingView and add wkWebView. Here is my code:
[self addSubview:_loadingView];
_wkWebView = [[WKWebView alloc] initWithFrame:self.frame];
_wkWebView.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, self.frame.size.height);
//Send a request to wkUrlconnection
NSURL *wkUrl = [NSURL URLWithString:self.wkUrlString];
NSURLRequest *wkRequest = [NSURLRequest requestWithURL:wkUrl];
//Here I want to check if it's loaded and then remove loadingView and add wkWebView
[_wkWebView loadRequest:wkRequest];
[self.loadingView removeFromSuperview];
[self addSubview:_wkWebView];
Can someone show me how to check while it's loading and if finish refresh the VC? Thank you for your answers.
I think the WKNavigationDelegate's webView:didFinishNavigation: delegate callback is what you're looking for.
Configure and present your activity indicator when you start to load and then stop and remove it from view when the callback is called.
For anyone who is experiencing the issue of a webpage containing multiple frames and therefore doing multiple loads which interrups your load animation, I have implemented the following and it works for me in all the situations I have come across so far:
Swift:
var loadCount: Int = 0
override func viewDidLoad() {
super.viewDidLoad()
startLoading()
webview.navigationDelegate = self
let request = URLRequest(url: url)
webview.load(request)
}
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
loadCount += 1
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
loadCount -= 1
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in
if self?.loadCount == 0 {
self?.stopLoading()
}
}
}
The basic idea is to start your load animation before you request the url, then count each request being made and only stop the load animation when your request count == 0. This is done after a slight delay as I find that some frames queue up requests synchronously so the next load will begin before the 0.1 second delay has completed.
( ͡° ͜ʖ ͡°)
for swift 4.2:
func webView(_ webView: WKWebView,
didFinish navigation: WKNavigation!){
print("loaded")
}
be sure to set delegate for webView in didLoad (or similar)
webView.navigationDelegate = self
class WebViewVC: UIViewController {
// MARK: IBOutlets
#IBOutlet weak var webView: WKWebView!
#IBOutlet weak var activityIndicator: UIActivityIndicatorView!
// MARK: Life cycle
override func viewDidLoad() {
super.viewDidLoad()
webView.navigationDelegate = self
loadWebsite()
}
}
// MARK: WKWebView
extension WebViewVC: WKNavigationDelegate {
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
activityIndicator.startAnimating()
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
activityIndicator.stopAnimating()
}
}
// MARK: Private methods
extension WebViewVC {
private func loadWebsite() {
guard let url = URL(string: "google.com") else { return }
let urlRequest = URLRequest(url: url)
webView.load(urlRequest)
}
}
If we load a webpage, we can forward it to safari, but this causes users to leave our app. Is there any way so that a user visits any webpage and then come back to our application.
If you want some browser type functionality for devices earlier then iOS7, you can use this inline browser
iOS 9 Update:
Apple has introduced a visible standard interface for browsing the web i.e. SFSafariViewController for iOS 9+ devices.
Example:
func showTutorial() {
if let url = URL(string: "https://www.example.com") {
let config = SFSafariViewController.Configuration()
config.entersReaderIfAvailable = true
let vc = SFSafariViewController(url: url, configuration: config)
present(vc, animated: true)
}
}
You can use a UIWebView to display the page in your application.
I wanted to add a more detailed answer for others in the future (key coding!) :
In the object library, search for WebKit View and add it to your ViewController
Place "import WebKit" under "import UIKit"
Create an outlet from the WebKit View you placed in your ViewController in your code directly under the opening "{"
Under "superViewDidLoad()", all you need is this:
let url = URL(string: "your_url_here"")
and
webview.load(URLRequest(url:url!))
and dassit!
I'll attach a copy of my code just in case I didn't explain it very well:
import UIKit
import WebKit
class WebsiteViewController: UIViewController {
#IBOutlet weak var webview: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
let url = URL(string: "https://www.eventbrite.com/e/pretty-in-petals-tea-party-tickets-43361370025")
webview.load(URLRequest(url: url!))
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Use a UIWebView Here's how to program one. Let me know if you need more help or examples
#user1706456 UIWebView is deprecated by Apple, You can use WKWebView for it.
Here's code to do that :
step1: Import WebKit
Step2:
//ViewController's LifeCycle.
override func loadView() {
let webConfiguration = WKWebViewConfiguration()
webView = WKWebView(frame: .zero, configuration: webConfiguration)
webView.uiDelegate = self
webView.navigationDelegate = self
view = webView
}
Step3 :
In ViewDidLoad:
let myURL = URL(string: "www.google.com")
let myRequest = URLRequest(url: myURL!)
webView.load(myRequest)
Step 4: WKWebView Delegate Methods to handle navigation and loading etc.
//MARK: - WKNavigationDelegate
extension GPWebViewController : WKNavigationDelegate {
func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
// Refreshing the content in case of editing...
}
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
}
}