Why my WKWebview inside my UIScrollView is not displayed? - ios

I need to add a WKWebview to load web content, inside the content view of UIScrollView.
I'm using the Apple code to load a web page, my outlet viewForWebview is linked correctly, and didFinish is called.
class ViewController: UIViewController, WKUIDelegate, WKNavigationDelegate {
var webView: WKWebView!
#IBOutlet var viewForWebview: UIView!
override func loadView() {
super.loadView()
let myConfiguration = WKWebViewConfiguration()
webView = WKWebView(frame: .zero, configuration: myConfiguration)
webView.uiDelegate = self
webView.navigationDelegate = self
viewForWebview = webView
}
override func viewDidLoad() {
super.viewDidLoad()
let url = URL(string: "https://www.google.com.au")
let request = URLRequest(url: url!)
webView.load(request)
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
print("Finished navigating to url \(String(describing: webView.url))")
}
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
print(error)
}
}
But my the WKWebview is blank:
Just to test, I tried to display the WKWebview directly inside the content view of the scroll view, and it works.
Why is it not working as subview of the content?

Don't override loadView for such actions , you need
class ViewController: UIViewController, WKUIDelegate, WKNavigationDelegate {
var webView: WKWebView!
#IBOutlet var viewForWebview: UIView!
override func viewDidLoad() {
super.viewDidLoad()
let myConfiguration = WKWebViewConfiguration()
webView = WKWebView(frame:.zero, configuration: myConfiguration)
webView.uiDelegate = self
webView.navigationDelegate = self
viewForWebview.addSubview(webView)
webView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
webView.topAnchor.constraint(equalTo: viewForWebview.topAnchor),
webView.bottomAnchor.constraint(equalTo: viewForWebview.bottomAnchor),
webView.leadingAnchor.constraint(equalTo: viewForWebview.leadingAnchor),
webView.trailingAnchor.constraint(equalTo: viewForWebview.trailingAnchor)
])
let url = URL(string: "https://www.apple.com")
let request = URLRequest(url: url!)
webView.load(request)
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
print("Finished navigating to url \(String(describing: webView.url))")
}
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
print(error)
}
}

Related

wkwebview not showing properly in landscape mode

This is how my storyboard looks
and below is my code
class ViewController: UIViewController,WKNavigationDelegate {//WKUIDelegate
#IBOutlet weak var webContainer: UIView!
var webView : WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
initMyWeb()
}
func initMyWeb() -> Void {
let myBlog = "https://google.com"
let myURL = URL(string: myBlog)
let request = URLRequest(url: myURL!)
// init and load request in webview.
webView = WKWebView(frame: self.webContainer.frame)
webView.navigationDelegate = self
webView.load(request)
self.webContainer.addSubview(webView)
self.webContainer.sendSubview(toBack: webView)
}
//MARK:- WKNavigationDelegate
func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
print(error.localizedDescription)
}
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
print("Start to load")
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
print("finish to load")
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
webView.frame = self.webContainer.frame
}
and when I run it in Landscape mode, it appear like this
My question is: How to make it adapt whole screen in landscape mode? I have given it size equal to webContainer view
Try this
webView = WKWebView(frame: self.webContainer.frame)
webView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
webView.navigationDelegate = self
webView.load(request)

How to add UIActivityIndicatorView to WKWebView?

I'm new to Swift and I need some help implementing the UIActivityInidicatorView to WKWebView. It should appear while the webpage is loading and disappear when the website finished loading.
Here is my code so far:
import UIKit
import WebKit
class ViewController: UIViewController {
#IBOutlet weak var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
let myURL = URL(string: "https://www.google.com")
let myRequest = URLRequest(url: myURL!)
webView.load(myRequest)
}
}
import UIKit
import WebKit
class ViewController: UIViewController, WKNavigationDelegate, WKUIDelegate {
var webView: WKWebView!
var activityIndicator: UIActivityIndicatorView!
override func viewDidLoad() {
webView = WKWebView(frame: CGRect.zero)
webView.navigationDelegate = self
webView.uiDelegate = self
view.addSubview(webView)
activityIndicator = UIActivityIndicatorView()
activityIndicator.center = self.view.center
activityIndicator.hidesWhenStopped = true
activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.gray
view.addSubview(activityIndicator)
webView.load(URLRequest(url: URL(string: "http://google.com")!))
}
func showActivityIndicator(show: Bool) {
if show {
activityIndicator.startAnimating()
} else {
activityIndicator.stopAnimating()
}
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
showActivityIndicator(show: false)
}
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
showActivityIndicator(show: true)
}
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
showActivityIndicator(show: false)
}
}
I finally got it working like this:
import UIKit
import WebKit
class ViewController: UIViewController, WKNavigationDelegate {
#IBOutlet weak var webView: WKWebView!
#IBOutlet weak var ActivityIndicator: UIActivityIndicatorView!
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
ActivityIndicator.stopAnimating()
}
override func viewDidLoad() {
super.viewDidLoad()
let myURL = URL(string: "https://www.google.com/")
let myRequest = URLRequest(url: myURL!)
webView.navigationDelegate = self
webView.load(myRequest)
}
}
Try this i hope this will help you
import UIKit
import WebKit
class ViewController: UIViewController, WKNavigationDelegate {
#IBOutlet weak var webView: WKWebView!
#IBOutlet weak var ActivityIndicator: UIActivityIndicatorView!
override func viewDidLoad() {
super.viewDidLoad()
let myURL = URL(string: "https://www.google.com")
let myRequest = URLRequest(url: myURL!)
webView.navigationDelegate = self
webView.load(myRequest)
}
func webView(_ webView: WKWebView,didStart navigation: WKNavigation!) {
print("Start Page Loading")
ActivityIndicator.statAnimating()
}
func webView(_ webView: WKWebView,didFinish navigation: WKNavigation!) {
print("Page loaded")
ActivityIndicator.stopAnimating()
}
}

How to add Activity Indicator to WKWebView (Swift 3)

I have a wkwebview in my app, and I want to add an activity indicator to it. I want it to where it appears when the webview is loading and disappears whenever it is finished loading, it disappears. Can you give me some code to do this? Here's my code right now:
#IBOutlet weak var Activity: UIActivityIndicatorView!
var webView : WKWebView!
#IBOutlet var containerView: UIView? = nil
override func viewDidLoad() {
super.viewDidLoad()
guard let url = URL(string: "http://ifunnyvlogger.wixsite.com/ifunnyvlogger/app-twitter") else { return }
webView = WKWebView(frame: self.view.frame)
webView.translatesAutoresizingMaskIntoConstraints = false
webView.isUserInteractionEnabled = true
webView.navigationDelegate = self
self.view.addSubview(self.webView)
let request = URLRequest(url: url)
webView.load(request)
}
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: #escaping (WKNavigationActionPolicy) -> Void) {
// Check if a link was clicked
if navigationAction.navigationType == .linkActivated {
// Verify the url
guard let url = navigationAction.request.url else { return }
let shared = UIApplication.shared
// Check if opening in Safari is allowd
if shared.canOpenURL(url) {
// Ask the user if they would like to open link in Safari
let alert = UIAlertController(title: "Do you want to open Safari?", message: nil, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Yes", style: .default, handler: { (alert: UIAlertAction) -> Void in
// User wants to open in Safari
shared.open(url, options: [:], completionHandler: nil)
}))
alert.addAction(UIAlertAction(title: "Opps, no.", style: .cancel, handler: nil))
present(alert, animated: true, completion: nil)
}
decisionHandler(.cancel)
}
decisionHandler(.allow)
}
func webViewDidStartLoad(_ : WKWebView) {
Activity.startAnimating()
}
func webViewDidFinishLoad(_ : WKWebView) {
Activity.startAnimating()
}
I'm creating an IOS app using xcode 8 and swift 3
Please, below code which is working fine.
#IBOutlet weak var Activity: UIActivityIndicatorView!
var webView : WKWebView!
#IBOutlet var containerView: UIView? = nil
override func viewDidLoad() {
super.viewDidLoad()
guard let url = URL(string: "http://www.facebook.com") else { return }
webView = WKWebView(frame: self.view.frame)
webView.translatesAutoresizingMaskIntoConstraints = false
webView.isUserInteractionEnabled = true
self.view.addSubview(self.webView)
let request = URLRequest(url: url)
webView.load(request)
// add activity
self.webView.addSubview(self.Activity)
self.Activity.startAnimating()
self.webView.navigationDelegate = self
self.Activity.hidesWhenStopped = true
}
Implement below these two delegate method:
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
Activity.stopAnimating()
}
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
Activity.stopAnimating()
}
Let me know if it is not working.
import UIKit
import WebKit
class ViewController: UIViewController, WKNavigationDelegate, WKUIDelegate {
var webView: WKWebView!
var activityIndicator: UIActivityIndicatorView!
override func viewDidLoad() {
webView = WKWebView(frame: CGRect.zero)
webView.navigationDelegate = self
webView.uiDelegate = self
view.addSubview(webView)
activityIndicator = UIActivityIndicatorView()
activityIndicator.center = self.view.center
activityIndicator.hidesWhenStopped = true
activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.gray
view.addSubview(activityIndicator)
webView.load(URLRequest(url: URL(string: "http://google.com")!))
}
func showActivityIndicator(show: Bool) {
if show {
activityIndicator.startAnimating()
} else {
activityIndicator.stopAnimating()
}
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
showActivityIndicator(show: false)
}
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
showActivityIndicator(show: true)
}
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
showActivityIndicator(show: false)
}
}
Swift 5 Version
The concept is simple enough to be ported to earlier swift versions.
This is a class we would use as a parent class anywhere we want a webview.
import UIKit
import WebKit
class CustomWebViewController: UIViewController, WKNavigationDelegate {
var activityIndicator: UIActivityIndicatorView!
override func viewDidLoad() {
super.viewDidLoad()
activityIndicator = UIActivityIndicatorView()
activityIndicator.center = self.view.center
activityIndicator.hidesWhenStopped = true
activityIndicator.style = .gray
activityIndicator.isHidden = true
view.addSubview(activityIndicator)
}
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
activityIndicator.isHidden = false
activityIndicator.startAnimating()
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
activityIndicator.stopAnimating()
activityIndicator.isHidden = true
}
}
If we have a UIViewController with a webview, we can just inherit from CustomWebViewController and it will take care of the rest for us. Remember to connect the webview IBOutlet.
import UIKit
import WebKit
class FirstViewController: CustomWebViewController {
#IBOutlet var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
webView.navigationDelegate = self
let url = URL(string: "https://google.com")
webView.load(URLRequest(url: url!))
}
}
In viewDidLoad you need to add the activityIndicator as a subView just as you did for your webView. Since it's an outlet, make sure the activityIndicator sits on top of your webView and you should be good to go. You also want to set activity.hidden to true when the webView stops loading.
It's also a good rule of thumb to lower case your 'Activity' outlet.
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(self.Activity)
guard let url = URL(string: "http://ifunnyvlogger.wixsite.com/ifunnyvlogger/app-twitter") else { return }
webView = WKWebView(frame: self.view.frame)
webView.translatesAutoresizingMaskIntoConstraints = false
webView.isUserInteractionEnabled = true
webView.navigationDelegate = self
self.view.addSubview(self.webView)
let request = URLRequest(url: url)
webView.load(request)
You also call activity.startAnimating in webViewDidFinishLoad(). Make sure you call activity.stopAnimating() when the webView finishes loading. Happy coding!
func webViewDidFinishLoad(_ : WKWebView) {
Activity.stopAnimating()
Activity.hidden = true
}
import UIKit
import WebKit
class ViewController: UIViewController, WKNavigationDelegate, WKUIDelegate {
var webView: WKWebView!
var activityIndicator: UIActivityIndicatorView!
override func viewDidLoad() {
webView = WKWebView(frame: CGRect.zero)
webView.navigationDelegate = self;
webView.uiDelegate = self
activityIndicator = UIActivityIndicatorView()
activityIndicator.hidesWhenStopped = true
activityIndicator.center = self.view.center
activityIndicator.style = UIActivityIndicatorView.Style.large
webView.addSubview(activityIndicator)
view = webView
let load_url = URL(string: "https://google.com/")!
webView.load(URLRequest(url: load_url))
activityIndicator.startAnimating()
let refresh = UIBarButtonItem(barButtonSystemItem: .refresh, target: webView, action: #selector(webView.reload))
toolbarItems = [refresh]
navigationController?.isToolbarHidden = false
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
title = webView.title
activityIndicator.stopAnimating()
}
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
activityIndicator.startAnimating()
}
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
activityIndicator.stopAnimating()
}
}
Please try the below code its working fine for me and please let me know if anything is wrong in it thanks in advance.
import UIKit
import WebKit
class WebViewController: UIViewController, WKUIDelegate, WKNavigationDelegate {
#IBOutlet weak var contentView: UIView!
#IBOutlet weak var activityIndicatorView: UIActivityIndicatorView!
override func viewDidLoad() {
super.viewDidLoad()
setupView()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.setupWebView()
self.loadData()
}
fileprivate func setupView() {
self.contentView.isHidden = true
self.activityIndicatorView.startAnimating()
}
fileprivate func setupWebView() {
let webConfiguration = WKWebViewConfiguration()
webView = WKWebView(frame: contentView.bounds, configuration: webConfiguration)
webView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
self.contentView.addSubview(webView)
self.webView.allowsBackForwardNavigationGestures = true
webView.uiDelegate = self
webView.navigationDelegate = self
}
fileprivate func loadData() {
if let url = URL(string: "http://google.com") {
/// For loading PDF content
if contentType == .pdf {
if let data = try? Data(contentsOf: url) {
self.webView.load(data, mimeType: "application/pdf", characterEncodingName: "", baseURL: url)
}
} else {
let request = URLRequest(url: url)
webView.load(request)
}
}
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
activityIndicatorView.stopAnimating()
self.contentView.isHidden = false
}
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
activityIndicatorView.stopAnimating()
}
}

WKWebView Content loaded function never get called

i try to get a function called after my Content inside WKWebView is fully loaded. I found the "didFinishNavigation" function at the Apple Swift WKNavigation Documentation.
func webView(webView: WKWebView!, didFinishNavigation navigation: WKNavigation!) {
println("WebView content loaded.")
}
But the function never get called.
import UIKit
import WebKit
class ViewController: UIViewController WKNavigationDelegate {
override func loadView() {
super.loadView()
self.webView = WKWebView(frame:self.containerView.frame, configuration: WKWebViewConfiguration())
self.containerView.addSubview(webView!)
self.containerView.clipsToBounds = true
}
override func viewDidLoad() {
super.viewDidLoad()
var url = NSURL(string:"http://google.com/")
var req = NSURLRequest(URL:url)
self.webView!.loadRequest(req)
}
func webView(webView: WKWebView!, didFinishNavigation navigation: WKNavigation!) {
println("WebView content loaded.")
}
}
You are not setting the navigationDelegate. Set it and it should be fine.
class ViewController: UIViewController, WKNavigationDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let noLayoutFormatOptions = NSLayoutFormatOptions(rawValue: 0)
let webView = WKWebView(frame: CGRectZero, configuration: WKWebViewConfiguration())
webView.setTranslatesAutoresizingMaskIntoConstraints(false)
webView.navigationDelegate = self
view.addSubview(webView)
view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[webView]|", options: noLayoutFormatOptions, metrics: nil, views: ["webView": webView]))
view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[webView]|", options: noLayoutFormatOptions, metrics: nil, views: ["webView": webView]))
let url = NSURL(string: "http://google.com")
let request = NSURLRequest(URL: url)
webView.loadRequest(request)
}
func webView(webView: WKWebView!, didFinishNavigation navigation: WKNavigation!) {
print("Finished navigating to url \(webView.url)");
}
}
And here is a bit better version with Swift 3.
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let configuration = WKWebViewConfiguration()
let webView = WKWebView(frame: .zero, configuration: configuration)
webView.translatesAutoresizingMaskIntoConstraints = false
webView.navigationDelegate = self
view.addSubview(webView)
[webView.topAnchor.constraint(equalTo: view.topAnchor),
webView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
webView.leftAnchor.constraint(equalTo: view.leftAnchor),
webView.rightAnchor.constraint(equalTo: view.rightAnchor)].forEach { anchor in
anchor.isActive = true
}
if let url = URL(string: "https://google.com/search?q=westworld") {
webView.load(URLRequest(url: url))
}
}
}
extension ViewController: WKNavigationDelegate {
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
print("Finished navigating to url \(webView.url)")
}
}
I made a simple mistake for not adding a subview to my View
view.addSubview(webView)
I have created a webView programmatically, here is the complete code
1.. import WebKit
2.. func viewDidLoad()
let request = URLRequest(url: url)
let webView = WKWebView(frame: view.frame)
view.addSubview(webView)
webView.navigationDelegate = self
webView.load(request)
3.. Implement extension for delegate methods
// MARK: WKWebView
extension ViewController: WKNavigationDelegate {
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
print("Start Request")
}
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
print("Failed Request")
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
print("Finished Request")
}

Activity Indicator won't stop spinning after WKWebView load finish

I am very new to Swift and iOS development so thank you so much in advance for helping me!
I have tried every example online and every page on this site and I cannot get my Activity Indicator to stop being displayed once the page completes loading in my WKWebview.
Any assistance would be so appreciated! Thank you!
import UIKit
import WebKit
class FirstViewController: UIViewController, WKUIDelegate, WKNavigationDelegate {
#IBOutlet var webView: WKWebView!
#IBOutlet var activityIndicator: UIActivityIndicatorView!
override func viewDidLoad() {
super.viewDidLoad()
webView.uiDelegate = self
activityIndicator.startAnimating()
activityIndicator.isHidden = true
activityIndicator.hidesWhenStopped = true
let url = Bundle.main.url(forResource: "Web/bulk_material_table", withExtension: "html")!
webView.loadFileURL(url, allowingReadAccessTo: url)
let request = URLRequest(url: url)
self.webView.load(request)
}
func showActivityIndicator(show: Bool) {
if show {
activityIndicator.startAnimating()
} else {
activityIndicator.stopAnimating()
}
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
showActivityIndicator(show: false)
}
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
showActivityIndicator(show: true)
}
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
showActivityIndicator(show: false)
}
}
Just replace
webView.uiDelegate = self
with
webView.navigationDelegate = self
And it will work because
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
showActivityIndicator(show: false)
}
is WKNavigationDelegate's delegate method.

Resources