I am trying to make an iOS app with Swift and I have sorted out the webView which works perfectly, however now i'd like to implement an activity indicator. It displays properly and is animated, however when the page is loaded, the activity indicator does not disappear.
This is my code:
import UIKit
import WebKit
class FirstViewController: UIViewController {
#IBOutlet var webview: WKWebView!
// #IBOutlet var bg: UIView!
// #IBOutlet var logo: UIImageView!
#IBOutlet var ActInd: UIActivityIndicatorView!
// #IBOutlet var LoadingLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
let url = URL(string: "https://www.google.com")
let request = URLRequest(url: url!)
webview.load(request)
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func webViewDidStartLoad(_ : WKWebView) {
ActInd.startAnimating()
//LoadingLabel.isHidden = true
//logo.isHidden = true
//bg.isHidden = true
}
func webViewDidFinishLoad(_ : WKWebView){
ActInd.stopAnimating()
// LoadingLabel.isHidden = true
//logo.isHidden = true
//bg.isHidden=true
}
}
I'd appreciate it enormously if someone could help me get the activity indicator to disappear.
Thank you in advance
Try setting
ActInd.hidesWhenStopped = true // In viewDidLoad
Conform to WKNavigationDelegate, and you can track webView processes..
The methods of the WKNavigationDelegate protocol help you implement custom behaviors that are triggered during a web view's process of accepting, loading, and completing a navigation request.
There are two methods that you can use :
func webView(WKWebView, didStartProvisionalNavigation: WKNavigation!)
Called when web content begins to load in a web view.
Here you can show the activity indicator
func webView(WKWebView, didFinish: WKNavigation!)
Called when the navigation is complete.
For more info check WKNavigationDelegate documentation
So here are the steps :
1- Conform to WKNavigationDelegate.
2- Assign your view controller to be your web view’s navigationDelegate.
3- Implement didStartProvisionalNavigation and didFinish methods
Example :
class ViewController: UIViewController, WKNavigationDelegate {
#IBOutlet var webview: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
webview.navigationDelegate = self
/*
....
*/
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
// hide/stop indicator
}
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
//show your activity
}
}
On view did load just start your indicator and on webViewDidFinishLoad just hide that loader.
The methods won't ever be called.
Because, you haven't set your ViewController as NavigationDelegate. It needs to conform to the WKNavigationDelegate. You can then set the delegate in the viewDidLoad() function:
webview.navigationDelegate = self
The 2 methods you're calling also don't seem to exist. These are the equivalent delegate methods: webView(:didCommit:) and webView(:didFinish:)
You can set "Hides when stopped" and "Animated" in the storyboard or do it programatically as it is explained in this answer.
You should also take a look at the API Design guidelines explaining how code should be written. Especially you should:
Follow case conventions. Names of types and protocols are UpperCamelCase. Everything else is lowerCamelCase.
Related
I added an activity indicator to my view controller via the main.storyboard and put it in my view controller via drag & drop method but when I try to do something with addSubView I get this error.
Thread 1: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
On the line: view.addSubview(ActInd)
The project is running on Swift 5.0 and Xcode 10.3. Switching back to Swift 4.2 makes no difference. I can debug the app but then it crashes when it comes to the piece of coding
import UIKit
import WebKit
class ViewController: UIViewController, WKNavigationDelegate {
var webView: WKWebView!
#IBOutlet weak var ActInd: UIActivityIndicatorView!
override func loadView() {
webView = WKWebView()
webView.navigationDelegate = self
view = webView
}
func loadPage(){
let url = URL(string: "SOMEURL")!
webView.load(URLRequest(url: url))
webView.allowsBackForwardNavigationGestures = true
}
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(ActInd)
ActInd.startAnimating()
ActInd.hidesWhenStopped = true
loadPage()
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
// Code runs when its finnished
ActInd.stopAnimating()
}
}
I wanted to have an activity indicator when my page was loading in the webview
It seems, var ActInd: UIActivityIndicatorView! is nil
First of all, you should check whether you correctly defined you ActInd: UIActivityIndicatorView in the storyboard. Possibly, you didn't drag the item from storyboard(xib) file to the swift ViewController file.
And don't forget to use super methods.
override func loadView() {
super.loadView()
}
I have a ViewController with WebKit and two buttons above it. I want WebKit to be fullscreen and buttons to be above it.
This is code of my ViewController:
#IBOutlet weak var webview: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
// here I am loading URLRequest
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func loadView() {
webview = WKWebView()
webview.navigationDelegate = self
view = webview
}
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
showLoading()
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
hideLoading()
}
This is what my storyboard looks like:
Methods showLoading() and hideLoading() are handling loading popup.
With this code buttons are not visible. When I remove function loadView() buttons are visible but methods showLoading() and hideLoading() are never called.
How can I achieve mentioned behavior: fullscreen webview with buttons and functional methods (showLoading() and hideLoading())
what happens in your current code is you arbitrarily replace the current view with your webview instance and that directly removes the current view's subviews (=your buttons) as well.
you can either
a)
insert the webview directly:
override func loadView() {
webview = WKWebView()
webview.navigationDelegate = self
view.insertSubview(webview, at: 0)
webview.frame = view.bounds
}
or
b)
add the WKWebView to your view in the Interface Builder under your buttons then connect the outlet and the delegate(s) from IB and you can remove your loadView() implementation entirely.
before posting this I was looking on the internet how to implement from cocoa pods MBCircularProgressBarView in iOS Swift WKWebKit to track progress of loading website.
I have tried with combination of some other progress bar codes but it didn't work.
I have tried to implement self.progressView.value = 0 in viewDidLoad
and
UIView.animate(withDuration: 1.0){
self.progressView.value = 100
}
in
didFinish navigation
which shows circular bar and animate but doesn't show proper loading progress.
Any idea how to make this work.
Make a class class WebpageViewController: UIViewController, UIWebViewDelegate containing:
#IBOutlet weak var activitySpinner: UIActivityIndicatorView!
#IBOutlet weak var activityLabel: UILabel!
override func viewDidAppear(_ animated: Bool)
{
activitySpinner.tintColor = R.color.YumaRed
activitySpinner.hidesWhenStopped = true
activityLabel.text = "Loading..."
webView.loadRequest(URLRequest(url: URL(string: "http://...")!))
}
func webViewDidStartLoad(_ webView: UIWebView)
{
activitySpinner.startAnimating()
}
func webViewDidFinishLoad(_ webView: UIWebView)
{
activitySpinner.stopAnimating()
activityLabel.isHidden = true
}
func webView(_ webView: UIWebView, didFailLoadWithError error: Error)
{
activitySpinner.stopAnimating()
}
override func viewDidLoad()
{
super.viewDidLoad()
webView.delegate = self
}
I've searched around, but I couldn't find how to disable zooming in iOS.
I have this in my viewDidLoad() but it doesn't do anything.
webView.scrollView.isMultipleTouchEnabled = false;
Any ideas?
You can remove the pinchGestureRecognizer from scrollView in delegate method didFinish navigation by conforming your ViewController to WKNavigationDelegate as below,
class ViewController: UIViewController, WKNavigationDelegate {
var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
// TODO: Initialize webView before setting the delegate
webView.navigationDelegate = self
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
if let pinchGesture = webView.scrollView.pinchGestureRecognizer {
webView.scrollView.removeGestureRecognizer(pinchGesture)
}
}
}
I am trying to get a webpage to appear in my swift application. I have added the WebView and wrote the following code in the controller class but when I run my app, there is only a white screen. Am I missing something?
class WebViewController: UIViewController {
#IBOutlet weak var webView: UIWebView!
override func viewDidLoad() {
super.viewDidLoad()
let WebView = UIWebView(frame: view.bounds)
let url = NSURL(string: "http://www.google.com")
let request = NSURLRequest(URL:url!)
WebView.loadRequest(request)
view.addSubview(WebView)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
Run your code in viewDidLayoutSubviews. You are setting the WebView's frame to the view's bounds. The view's frame has not fully loaded yet.
Never mind, I'm an idiot and forgot the s in http thanks all.
You need to tell the webView who is its delegate, just binding the outlet won't be enough.
In viewDidLoad add this:
self.webView.delegate = self
Then you need to conform to UIWebViewDelegate (which you are already doing, but I suggest you extend your view controller instead):
extension WebViewController: UIWebViewDelegate {
func webViewDidStartLoad(_ webView: UIWebView) {
print("Loading")
}
func webViewDidFinishLoad(_ webView: UIWebView) {
print("Finished")
}
}
And last but not least, you need to allow your application to load external URL's by adding a transport security, I suggest you check this post.
Please note I'm using Swift 3, you may need to make little changes.