How to fix black screen in load of webview url from my own class

被刻印的时光 ゝ 提交于 2020-08-10 19:14:27

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!