kumar barian
kumar barian

Reputation: 139

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

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

Upvotes: 1

Views: 1811

Answers (2)

gianpispi
gianpispi

Reputation: 611

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.

enter image description here

Upvotes: 1

Habin Lama
Habin Lama

Reputation: 559

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.

Upvotes: 2

Related Questions