I am a beginner in iOS
development. Now I'm on a page that shows a webView
when I press a button. I'm marking the indicator
when I'm loading it. I can't see it. I marked it to be visible when loading, but what's the problem?
storyboard
ButtonEvent
@IBAction func DetailFuc(_ sender: Any) {
}
WebView Controller
import Foundation
import UIKit
import WebKit
let globalUrl = Global()
class UsageDetail: UIViewController {
@IBOutlet weak var UsageWebView: WKWebView!
@IBOutlet weak var usageIndicator: UIActivityIndicatorView!
func loadWebPage() {
let detailUrl = globalUrl.getAgreeURL()
let myUrl = URL(string: detailUrl)
let myRequest = URLRequest(url: myUrl!)
UsageWebView.load(myRequest)
UsageWebView.addObserver(self, forKeyPath: #keyPath(WKWebView.isLoading), options: .new, context: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
loadWebPage()
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == "loading" {
if UsageWebView.isLoading {
usageIndicator.startAnimating()
usageIndicator.isHidden = false
} else {
usageIndicator.stopAnimating()
usageIndicator.isHidden = true
}
}
}
}
I took out the Internet line and tried it, but I couldn't see it.
In addition, I would like to use the indicator as a png file. I have a large number of png files. How can I use an animation of an indicator with it?
Thanks in advance
*************************** Edit start ******************************
I tried it after I saw the answer but there was an error.
import Foundation
import UIKit
import WebKit
let globalUrl = Global()
class UsageDetail: UIViewController {
@IBOutlet weak var UsageWebView: WKWebView!
@IBOutlet weak var usageIndicator: UIActivityIndicatorView!
func loadWebPage() {
let detailUrl = globalUrl.getAgreeURL()
let myUrl = URL(string: detailUrl)
let myRequest = URLRequest(url: myUrl!)
UsageWebView.load(myRequest)
UsageWebView.addObserver(self, forKeyPath: #keyPath(WKWebView.isLoading), options: .new, context: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
loadWebPage()
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == "loading" {
if UsageWebView.isLoading {
usageIndicator.startAnimating()
usageIndicator.isHidden = false
} else {
usageIndicator.stopAnimating()
usageIndicator.isHidden = true
}
}
}
extension UsageDetail : WKNavigationDelegate { // get error 'Declaration is only valid at file scope'
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
usageIndicator.startAnimating()
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
usageIndicator.stopAnimating()
}
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
usageIndicator.stopAnimating()
}
}
}
*************************** EditTWO start ******************************
//
// UsageDetail.swift
// dadadac
//
// Created by taehong on 06/09/2019.
// Copyright © 2019 Smart Core. All rights reserved.
//
import Foundation
import UIKit
import WebKit
let globalUrl = Global()
class UsageDetail: UIViewController {
@IBOutlet weak var UsageWebView: WKWebView!
@IBOutlet weak var usageIndicator: UIActivityIndicatorView!
//MARK: View controller lifecycle
override func viewDidLoad() {
super.viewDidLoad()
loadWebPage()
}
//MARK: initialise webView
func loadWebPage() {
let detailUrl = "globalUrl.getAgreeURL()"
guard let myUrl = URL(string: detailUrl) else {
//report invalid URL
return
}
let myRequest = URLRequest(url: myUrl)
UsageWebView.navigationDelegate = self //Cannot assign value of type 'UsageDetail' to type 'WKNavigationDelegate?'
UsageWebView.load(myRequest)
}
extension UsageDetail : WKNavigationDelegate { // Declaration is only valid at file scope
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
usageIndicator.startAnimating()
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
usageIndicator.stopAnimating()
}
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
usageIndicator.stopAnimating()
}
}
}
I can see Two Error Cannot assign value of type 'UsageDetail' to type 'WKNavigationDelegate?'
And Declaration is only valid at file scope
*************************** EditTWO end ******************************
Adding observer is also not a bad approach but I think easiest way will be to conforms the WKNavigationDelegate
and also try to avoid force unwrapping when creating URL (if you have some spaces or bad characters this will crash your app. So always try to make you of optional chaining) like I mentioned below
Calling loadWebPage in viewDidLoad.
import Foundation
import UIKit
import WebKit
let globalUrl = Global()
class UsageDetail: UIViewController {
@IBOutlet weak var UsageWebView: WKWebView!
@IBOutlet weak var usageIndicator: UIActivityIndicatorView!
//MARK: View controller lifecycle
override func viewDidLoad() {
super.viewDidLoad()
loadWebPage()
}
//MARK: initialise webView
private func loadWebPage() {
let detailUrl = "globalUrl.getAgreeURL()"
guard let myUrl = URL(string: detailUrl) else {
//report invalid URL
return
}
let myRequest = URLRequest(url: myUrl)
UsageWebView.navigationDelegate = self
UsageWebView.load(myRequest)
}
}
extension UsageDetail : WKNavigationDelegate {
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
usageIndicator.startAnimating()
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
usageIndicator.stopAnimating()
}
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
usageIndicator.stopAnimating()
}
}