如何修复我自己 class 加载 webview url 时的黑屏

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

我正在创建一个 SDK 以从用户那里获取 url 并加载。所以我打算用 WKWebview 创建我自己的 class。但是我遇到了一些关于实例成员 webView cannot be used on type MyWebView(UIview)

的问题

我的代码:

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

我的视图控制器:

class ViewController: UIViewController {

    var webView =  MyWebView()
    

    override func viewDidLoad() {
        super.viewDidLoad()
        view = webView
        webView.passUrl(url: "https://www.swiggy.com")
    }
}

当我 运行 时,我的屏幕变黑了。不知道我在做什么。任何帮助都会很棒。

谢谢

我不会将您的网络视图分配给视图控制器中的主视图。尝试将其添加为子视图:

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),
])

更新 passUrl 如下:

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

这样你应该可以看到网页。

因为你只能调用 passUrl 方法一次,否则它会继续创建 web 视图,并将它们添加到视图层次结构中,我会像这样更新 MyWebView class:

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

我在你发布的项目上试过了,效果很好。

试试这个代码。经过测试并为我工作。 MyWebViewClass

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

检查一下,如果这不能解决问题,请告诉我。