Swift 3: Preload SecondViewController's WKWebView ahead of click - ios

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)
}

Related

How to Detect Back Swipe in WkWebView

Is it possible to detect a back swipe in a web view when there has not been any forward navigation? The following code works fine if the user has moved off the first page but I want to know if they back swiped while on that page.
Update - This is the code I'm using after modifying it per comments. I added the navigation back function and the swipe gesture.
class WebViewClient: UIViewController, WKUIDelegate, WKNavigationDelegate, UIGestureRecognizerDelegate
{
var webView: WKWebView!
public func load(pageLink page: String)
{
print("Opening: " + page)
if webView != nil
{
if let myURL = URL(string:page)
{
webUrlRequest = page
let myRequest = URLRequest(url: myURL)
webView.load(myRequest)
}
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!)
{
print("Opened: " + webUrlRequest)
}
override func loadView()
{
let pref = WKPreferences()
pref.javaScriptEnabled = true
let config = WKWebViewConfiguration()
config.preferences = pref
webView = WKWebView(frame: .zero, configuration: config)
webView.uiDelegate = self
webView.navigationDelegate = self
webView.allowsBackForwardNavigationGestures = true
view = webView
}
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: #escaping (WKNavigationActionPolicy) -> Void)
{
if navigationAction.navigationType == .backForward && webView.backForwardList.backList.count == 0
{
print("Can't go back any more")
}
decisionHandler(.allow)
}
#objc func backNavigationFunction(_ sender: UIScreenEdgePanGestureRecognizer)
{
let dX = sender.translation(in: view).x
if sender.state == .ended
{
let fraction = abs(dX / view.bounds.width)
if fraction >= 0.35
{
print("Back swipe")
//back navigation code here
}
}
}
override func viewDidLoad()
{
super.viewDidLoad()
let swipeGesture = UIScreenEdgePanGestureRecognizer(target: self, action: #selector(backNavigationFunction(_:)))
swipeGesture.edges = .left
swipeGesture.delegate = self
webView.addGestureRecognizer(swipeGesture)
}
}
I would implement a UIScreenEdgePanGestureRecognizer to handle this. Add the following to your viewDidLoad
let swipeGesture = UIScreenEdgePanGestureRecognizer(target: self, action: #selector(backNavigationFunction(_:)))
swipeGesture.edges = .left
swipeGesture.delegate = self
view.addGestureRecognizer(swipeGesture)
Then, implement a function to handle the backNavigationFunction like below:
#objc func backNavigationFunction(_ sender: UIScreenEdgePanGestureRecognizer) {
let dX = sender.translation(in: view).x
if sender.state == .ended {
let fraction = abs(dX / view.bounds.width)
if fraction >= 0.35 {
//back navigation code here
}
}
}
Don't forget to make the ViewController inherit from the UIGestureRecognizerDelegate class (i.e. class WebViewController: UIViewController, WKUIDelegate, WKNavigationDelegate, UIGestureRecognizerDelegate). The delegate in question here is UIGestureRecognizerDelegate but I anticipate you'll need the others as well.

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 onfinish load event of a UIWebView

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.
}

Swift WKWebView and Javascript Interaction

I've been having trouble getting a WKWebView in Swift to trigger some javascript in the loaded web page. Im just trying to use javascript to change a background color on the website if the user swipes left, swipes right, or clicks a button. Any help is greatly appreciated.
import UIKit
import WebKit
class myViewController: UIViewController, WKNavigationDelegate {
#IBOutlet var container: UIView!
var webView: WKWebView?
override func viewDidLoad() {
super.viewDidLoad()
self.webView = WKWebView()
container.addSubview(webView!)
webView?.allowsBackForwardNavigationGestures = true
webView?.navigationDelegate = self
let leftSwipe = UISwipeGestureRecognizer(target: self, action: #selector(myViewController.handleSwipes(_:)))
let rightSwipe = UISwipeGestureRecognizer(target: self, action: #selector(myViewController.handleSwipes(_:)))
leftSwipe.direction = .Left
rightSwipe.direction = .Right
view.addGestureRecognizer(leftSwipe)
view.addGestureRecognizer(rightSwipe)
}
override func viewDidAppear(animated: Bool) {
let frame = CGRectMake(0, 0, container.bounds.width, container.bounds.height)
webView!.frame = frame
let url = NSURL(string: "https://www.google.com")
let request = NSURLRequest(URL: url!)
self.webView!.loadRequest(request)
}
#IBAction func buttonClick(sender: AnyObject) {
webView?.evaluateJavaScript("document.getElementByID('hplogo').style.backgroundColor='red';", completionHandler: nil)
}
func handleSwipes(sender:UISwipeGestureRecognizer){
if (sender.direction == .Left){
webView?.evaluateJavaScript("document.getElementByID('hplogo').style.backgroundColor='black';", completionHandler: nil)
}
if (sender.direction == .Right){
webView?.evaluateJavaScript("document.getElementByID('hplogo').style.backgroundColor='green';", completionHandler: nil)
}
}
func webView(webView: WKWebView, didFinishNavigation navigation: WKNavigation!) {
webView?.evaluateJavaScript("document.getElementByID('hplogo').style.backgroundColor='red';", completionHandler: nil)
}
}
You misspelled the Javascript's function name. It should be getElementById instead of getElementByID:
document.getElementById('hplogo').style.backgroundColor = '...'

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