Swift onfinish load event of a UIWebView - ios

I'm loading a pdf in WebView from my server with this code :
webView = UIWebView(frame: CGRectMake(0, y, screenSize.width, screenSize.height-y))
let url : NSURL! = NSURL(string: urlFile)
webView?.loadRequest(NSURLRequest(URL: url))
webView?.opaque = false;
webView?.backgroundColor = UIColor.clearColor()
webView?.scalesPageToFit = true;
self.view.addSubview(webView!)
This code works but how can i receive an event "onPageLoad"?
sorry for bad english, i'm italian(:

You need to implement UIWebViewDelegate like this and use webViewDidFinishLoad to know the page is loaded successfully, for that set the webView delegate with your viewController like this, and implement the webViewDidFinishLoad method inside your viewController like below example.
import UIKit
class ViewController: UIViewController, UIWebViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
webView = UIWebView(frame: CGRectMake(0, y, screenSize.width, screenSize.height-y))
let url : NSURL! = NSURL(string: urlFile)
webView?.loadRequest(NSURLRequest(URL: url))
webView?.opaque = false;
webView?.backgroundColor = UIColor.clearColor()
webView?.scalesPageToFit = true;
webView?.delegate = self// Add this line to set the delegate of webView
self.view.addSubview(webView!)
}
func webViewDidFinishLoad(webView : UIWebView) {
//Page is loaded do what you want
}
}

In case someone is looking solution for WKWebView, implement WKNavigationDelegate:
add webView.navigationDelegate = self
and then use:
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
}

After webView?.loadRequest(NSURLRequest(URL: url)) this, set the webView to self (Write the below line).
webView.delegate = self
Implement the webview delegate methods.
You will get callback in func webViewDidFinishLoad(_ webView: UIWebView) on completing the page load.
func webViewDidFinishLoad(webView: UIWebView) {
//handle the callback here when page load completes
}

Just use effective with ;
func webViewDidFinishLoad(webView : UIWebView) {
// Here your loaded codes.
}

Related

ViewController is loading always the same link

I am new to swift and ios.The View Controller launch always the same link and do do not show the grid menu with buttons that is in second scene.What i am doing wrong here?
I have in main.storyboard three scene.
In the first scene is navigation.The second scene is a grid menu with buttons that depending on the button click will open a link in webview located in the 3rd scene.The third scene includes a view that should open a specific link depending on the click button in step 2
import UIKit
import WebKit
class ViewController: UIViewController, WKNavigationDelegate {
var webView : WKWebView!
var webi:String = "https://www.google.al"
override func viewDidLoad() {
print("‼️OMG:viewDidLoad", webi)
super.viewDidLoad()
let url = URL(string: webi)!
webView.load(URLRequest(url: url))
let refresh = UIBarButtonItem(barButtonSystemItem: .refresh, target: webView, action: #selector(webView.reload))
toolbarItems = [refresh]
navigationController?.isToolbarHidden = false
}
override func loadView() {
webView = WKWebView()
webView.navigationDelegate = self
view = webView
}
#IBAction func Menu1(_ sender: Any) {
print("‼️OMG:viewDidLoad with menu1")
webi = "https://www.menu1.com"
}
#IBAction func Menu2(_ sender: Any) {
print("‼️OMG:viewDidLoad with menu1")
webi = "https://www.menu2.com"
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
title = webView.title
}
}
Your problem is that you change the urlStr webi without reloading the webview again
func refresh() {
let url = URL(string: webi)!
webView.load(URLRequest(url: url))
}
#IBAction func Menu1(_ sender: Any) {
print("‼️OMG:viewDidLoad with menu1")
webi = "https://www.menu1.com"
self.refresh()
}
#IBAction func menu2(_ sender: Any) {
print("‼️OMG:viewDidLoad with menu1") // other link
webi = "https://www.menu1.com"
self.refresh()
}
///
Navigation->buttons Menu VC -> webViewVC
while your are in buttons menu
let vc = ViewController()
vc.webi = "" // set link according to the clicked button
self.navigationController?.pushViewController(vc,animated:true)
Look to this Demo

Unable to start Activity Indicator in Swift 3?

I am new to IOS. I am trying to implement activity indicator while loading web view, but I am unable to do that.While debugging I encounter that animator is starting but it is not getting visible. I am using swift 3. Here my code is as below.Please let me know what I am doing wrong. If anyone have good resource to learn about activity indicator please mention that also.
class ViewController: UIViewController,UIWebViewDelegate {
var WebView: UIWebView!
override func viewDidLoad()
{
super.viewDidLoad()
WebView = UIWebView(frame: UIScreen.main.bounds)
WebView.delegate = self
view.addSubview(WebView)
if let url = URL(string: "https://apple.com")
{
let request = URLRequest(url: url)
WebView.loadRequest(request)
}
activityindicator.startAnimating()
activityindicator.color = UIColor.black
activityindicator.alpha = 1
activityindicator.isHidden = false
}
// weak var activityindicator: UIActivityIndicatorView!
let activityindicator = UIActivityIndicatorView()
func webViewDidStartLoad(_ webView: UIWebView)
{
activityindicator.startAnimating()
activityindicator.color = UIColor.black
activityindicator.alpha = 1
activityindicator.isHidden = false
UIApplication.shared.isNetworkActivityIndicatorVisible = true
}
func webViewDidFinishLoad(_ webView: UIWebView)
{
UIApplication.shared.isNetworkActivityIndicatorVisible = false
activityindicator.stopAnimating()
activityindicator.alpha = 0
activityindicator.isHidden = true
}
func webView(webView: UIWebView, didFailLoadWithError error: NSError)
{
activityindicator.isHidden = true
}
}
Looks like the activity indicator is not added to view. Similar to how we are adding webview, center and add the indicator in viewDidLoad (code below).
activityindicator.center = self.view.center
view.addSubview(activityindicator)
Also I would suggest moving the global declarations to one place. i.e move the indicator declaration let activityindicator = UIActivityIndicatorView(), to be below webview's on top, instead of middle of class. This helps in quick readability.
Here is your full code. Now it's working -
import UIKit
class ViewController: UIViewController,UIWebViewDelegate {
var WebView: UIWebView!
override func viewDidLoad()
{
super.viewDidLoad()
WebView = UIWebView(frame: UIScreen.main.bounds)
WebView.delegate = self
view.addSubview(WebView)
if let url = URL(string: "https://apple.com")
{
let request = URLRequest(url: url)
WebView.loadRequest(request)
}
activityindicator.startAnimating()
activityindicator.center = self.view.center
view.addSubview(activityindicator)
activityindicator.color = UIColor.black
activityindicator.alpha = 1
}
// weak var activityindicator: UIActivityIndicatorView!
let activityindicator = UIActivityIndicatorView()
func webViewDidStartLoad(_ webView: UIWebView)
{
activityindicator.startAnimating()
activityindicator.color = UIColor.black
activityindicator.alpha = 1
activityindicator.isHidden = false
UIApplication.shared.isNetworkActivityIndicatorVisible = true
}
func webViewDidFinishLoad(_ webView: UIWebView)
{
UIApplication.shared.isNetworkActivityIndicatorVisible = false
activityindicator.stopAnimating()
activityindicator.alpha = 0
activityindicator.isHidden = true
}
func webView(webView: UIWebView, didFailLoadWithError error: NSError)
{
activityindicator.isHidden = true
}
}

Swift 3: Preload SecondViewController's WKWebView ahead of click

I need some help.
I want to preload my webView in Second View Controller after the webView in the First View Controller is done.
I believe I need to use a notification center post/observe to call my loadWebView-function in my Second View Controller but don't know how. Any suggestions is appreciated.
FirstViewController.swift
import UIKit;
import WebKit;
class FirstViewController: UIViewController, WKNavigationDelegate {
let webView:WKWebView = WKWebView(frame: CGRectMake(0, 0, UIScreen.main.bounds.width, UIScreen.main.bounds.height))
func webView(_ webView: WKWebView,
didFinish navigation: WKNavigation!) {
print("loaded!")
webView.isHidden = false
}
override func viewDidLoad() {
super.viewDidLoad()
let url = URL(string: "https://www.google.com")
webView.navigationDelegate = self
webView.load(URLRequest(url: url!))
webView.isHidden = true
self.view.addSubview(webView)
}
}
SecondViewController.swift
import UIKit
import WebKit
class SecondViewController: UIViewController, WKNavigationDelegate {
let webView:WKWebView = WKWebView(frame: CGRectMake(0, 0, UIScreen.main.bounds.width, UIScreen.main.bounds.height))
func webView(_ webView: WKWebView,
didFinish navigation: WKNavigation!) {
print("loaded!")
webView.isHidden = false
}
override func viewDidLoad() {
super.viewDidLoad()
}
func loadWebView() {
let url = URL(string: "https://www.amazon.com")
webView.navigationDelegate = self
webView.load(URLRequest(url: url!))
webView.isHidden = true
self.view.addSubview(webView)
}
}
In First VC :
func webView(_ webView: WKWebView,
didFinish navigation: WKNavigation!) {
//Post notification
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "WebViewFinishedLoading"), object: nil)
}
In Second VC:
override func viewDidLoad() {
super.viewDidLoad()
// Add observer for your notification
NotificationCenter.default.addObserver(self, selector: #selector(loadWebView), name: NSNotification.Name(rawValue: "WebViewFinishedLoading"), object: nil)
}
//Remove observer in deinit
deinit {
NotificationCenter.default.removeObserver(self)
}

WKWebView not resizing when content changing

WKWebView is not resizing when content changing.
Here is a code snippet:
#IBOutlet weak var containingView: UIView!
var webView: WKWebView!
override func viewDidLoad()
{
super.viewDidLoad()
let contentController = WKUserContentController();
self.webView = WKWebView(frame: CGRectMake(0, 0, self.view.frame.width, self.view.frame.height), configuration: WKWebViewConfiguration())
self.webView.autoresizingMask = [.FlexibleHeight]
self.webView.loadHTMLString(__, baseURL: __))
self.webView.scrollView.bounces = false
self.webView.scrollView.scrollEnabled = false
self.containingView.addSubview(self.webView)
}
What func should be added so I could intercept content size being changed and change the containingView size accordingly?
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
print("webview did enter did finish navigation")
webView.evaluateJavaScript("document.readyState", completionHandler: { (complete, error) in
if complete != nil {
webView.evaluateJavaScript("document.body.scrollHeight", completionHandler: { (result, error) in
if let heightOfContent = result as? CGFloat {
}
})
}
})
}
What halped me was to have small initial WKWebView height
webView = WKWebView(frame: CGRectMake(0, 0, self.view.frame.width, 150), configuration: configuration)
instead of
webView = WKWebView(frame: CGRectMake(0, 0, self.view.frame.width, self.view.frame.height), configuration: configuration)
Conceptually in objective c you should do like below.
Two things:
Make sure to have these properties:
self.webView.scalesPageToFit = YES;
self.webView.contentMode = UIViewContentModeScaleAspectFit;
And finally calculate webView content height as :-
webView.isLoading is one of the most important property. Actually in a single call to a web url it is called multiple times.
- (void)webViewDidFinishLoad:(UIWebView *)webView{
if (webView.isLoading == NO)// as it is called multiple times so wait untill last call
{
CGFloat height = [[webView stringByEvaluatingJavaScriptFromString:#"document.height"] floatValue];
}
}
This is how you should compute web view height.
you can have a look here as WKWebView don't have a delete which you can use to get content size instead use KVO:
KVO example
May be it will help you more!

Connect a UIProgressView to a UIWebView - Swift/Objective-c

I've got a UIWebView on my storyboard, loading a page from my blog.
I'd like to put also a UIProgressView there... but I don't really know how to connect that to my Web View.
Can you help me?
PS: My main project is in Swift, but if you have a solution working with Objective-C, post it anyway and I'll try to convert it :)
Thanks
Thy this out in swift 3
override func viewDidLoad() {
super.viewDidLoad()
let url = NSURL(string: "https://topdigital.agency")
let request = NSURLRequest(url: url as! URL)
webView.loadRequest(request as URLRequest)
webView.delegate=self
}
func webViewDidStartLoad(_ webView: UIWebView) {
self.progressView.setProgress(0.1, animated: false)
}
func webViewDidFinishLoad(_ webView: UIWebView) {
self.progressView.setProgress(1.0, animated: true)
}
func webView(_ webView: UIWebView, didFailLoadWithError error: Error) {
self.progressView.setProgress(1.0, animated: true)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
One way is to use the UIWebViewDelegate. Just set the webview.delegate = self. The UIActivityIndicator will be in the right corner of the UINavigationBar. If you have no navigation bar, you can just set a position for the UIActivityIndicator and call activityIndicator.stopAnimationg() to stop the animation.
func webViewDidStartLoad(webView: UIWebView) { //start
var activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: .White)
var activityBarButtonItem = UIBarButtonItem(customView: activityIndicator)
navigationItem.rightBarButtonItem = activityBarButtonItem
activityIndicator.startAnimating()
}
func webViewDidFinishLoad(webView: UIWebView) { //stop
navigationItem.rightBarButtonItem = nil
}

Resources