问题
I am creating one SDK to get the url from user and load. So ai m creating my own class with WKWebview
. But i am getting few issues about Instance member webView
cannot be used on type MyWebView(UIview)
My code :
import Foundation
import WebKit
public class MyWebView: UIView, WKNavigationDelegate {
// initialize the view
var webView: WKWebView!
// get the url and load the page
public func passUrl(url: String) {
guard let url = URL(string: url) else { return }
webView = WKWebView()
webView.navigationDelegate = self
webView.load(URLRequest(url: url))
webView.allowsBackForwardNavigationGestures = true
webView.addObserver(self, forKeyPath: "URL", options: .new, context: nil)
}
// Observe value
override public func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if let key = change?[NSKeyValueChangeKey.newKey] {
print("URL Changes: \(key)")
let alert = UIAlertController(title: "URL Changed", message: "\(key)", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Yes", style: .default, handler: nil))
alert.addAction(UIAlertAction(title: "No", style: .cancel, handler: nil))
self.window?.rootViewController?.present(alert, animated: true, completion: nil)
}
}
}
My view controller :
class ViewController: UIViewController {
var webView = MyWebView()
override func viewDidLoad() {
super.viewDidLoad()
view = webView
webView.passUrl(url: "https://www.swiggy.com")
}
}
When i run, i am getting my screen as black. Not sure what i am doing wong. Any help would be great.
Thanks
回答1:
Try this code. Tested and working for me. MyWebView Class
import Foundation
import WebKit
public class MyWebView: UIView, WKNavigationDelegate {
// initialize the view
let view: WKWebView = {
let view = WKWebView()
return view
}()
// get the url and load the page
public func passUrl(url: String) {
guard let url = URL(string: url) else { return }
view.navigationDelegate = self
view.load(URLRequest(url: url))
view.allowsBackForwardNavigationGestures = true
view.addObserver(self, forKeyPath: "URL", options: .new, context: nil)
}
// Observe value
override public func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if let key = change?[NSKeyValueChangeKey.newKey] {
print("URL Changes: \(key)")
let alert = UIAlertController(title: "URL Changed", message: "\(key)", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Yes", style: .default, handler: nil))
alert.addAction(UIAlertAction(title: "No", style: .cancel, handler: nil))
self.window?.rootViewController?.present(alert, animated: true, completion: nil)
}
}
public override init(frame: CGRect) {
super.init(frame: frame)
setupView()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setupView() {
view.translatesAutoresizingMaskIntoConstraints = false
addSubview(view)
NSLayoutConstraint.activate([
view.topAnchor.constraint(equalTo: topAnchor),
view.leadingAnchor.constraint(equalTo: leadingAnchor),
view.trailingAnchor.constraint(equalTo: trailingAnchor),
view.bottomAnchor.constraint(equalTo: bottomAnchor),
])
}
}
ViewController Class
import UIKit
class ViewController: UIViewController {
var webView = MyWebView()
override func viewDidLoad() {
super.viewDidLoad()
webView.passUrl(url: "https://www.swiggy.com")
}
override func loadView() {
view = webView
}
}
Check it if this does not fix the problem let me know.
回答2:
I wouldn't assign your web view to the main view in the view controller. Try to add it as a subview:
webView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(webView)
NSLayoutConstraint.activate([
webView.topAnchor.constraint(equalTo: view.topAnchor),
webView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
webView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
webView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
])
Update the passUrl ass follows:
public func passUrl(url: String) {
guard let url = URL(string: url) else { return }
webView = WKWebView()
webView.navigationDelegate = self
webView.load(URLRequest(url: url))
webView.allowsBackForwardNavigationGestures = true
webView.addObserver(self, forKeyPath: "URL", options: .new, context: nil)
webView.translatesAutoresizingMaskIntoConstraints = false
addSubview(webView)
NSLayoutConstraint.activate([
webView.topAnchor.constraint(equalTo: topAnchor),
webView.leadingAnchor.constraint(equalTo: leadingAnchor),
webView.trailingAnchor.constraint(equalTo: trailingAnchor),
webView.bottomAnchor.constraint(equalTo: bottomAnchor),
])
}
This way you should see the web page.
Since you can only call the passUrl method once, otherwise it will continue to create web views, and add them to the view hierarchy, I would update the MyWebView class like this:
public class MyWebView: UIView, WKNavigationDelegate {
// initialize the view
var webView: WKWebView!
// override the init to be able to create and add to the view only one instance of the WKWebView
public override init(frame: CGRect) {
super.init(frame: frame)
webView = WKWebView()
webView.navigationDelegate = self
webView.allowsBackForwardNavigationGestures = true
webView.addObserver(self, forKeyPath: "URL", options: .new, context: nil)
webView.translatesAutoresizingMaskIntoConstraints = false
addSubview(webView)
NSLayoutConstraint.activate([
webView.topAnchor.constraint(equalTo: topAnchor),
webView.leadingAnchor.constraint(equalTo: leadingAnchor),
webView.trailingAnchor.constraint(equalTo: trailingAnchor),
webView.bottomAnchor.constraint(equalTo: bottomAnchor),
])
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// get the url and load the page
public func passUrl(url: String) {
guard let url = URL(string: url) else { return }
webView.load(URLRequest(url: url))
}
// Observe value
override public func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if let key = change?[NSKeyValueChangeKey.newKey] {
print("URL Changes: \(key)")
let alert = UIAlertController(title: "URL Changed", message: "\(key)", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Yes", style: .default, handler: nil))
alert.addAction(UIAlertAction(title: "No", style: .cancel, handler: nil))
self.window?.rootViewController?.present(alert, animated: true, completion: nil)
}
}
}
I tried it on the project you posted and it works.
来源:https://stackoverflow.com/questions/63150713/how-to-fix-black-screen-in-load-of-webview-url-from-my-own-class