Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.7k views
in Technique[技术] by (71.8m points)

ios - WKWebView full screen with hidesBarsOnSwipe of navigation bar

I want to make a custom browser working with ARKit in background. I set UINavigationController as rootViewController and push a custom controller WebViewController in the navigation stack. WebViewController creates WKWebView and ARSCNView and pushes them in its view hierarchy. WKWebView and ARSCNView are laid out using auto layout constraints. I also added navigation bar and tool bar for webpage navigating UI with auto show/hide on swiping.

class WebpageViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        // Set up navigation bar and tool bar
        navigationController!.interactivePopGestureRecognizer?.isEnabled = false
        navigationController!.hidesBarsOnSwipe = true
        navigationController!.delegate = self

        ...

        // Set up ARSCNView and WKWebView
        arscnView = ARSCNView(frame: .zero)
        arscnView.translatesAutoresizingMaskIntoConstraints = false
        arscnView.session.delegate = self
        arscnView.showsStatistics = false
        arscnView.scene = SCNScene()
        view.addSubview(arscnView)

        let config = WKWebViewConfiguration()
        webView = WKWebView(frame: .zero, configuration: config)
        webView.translatesAutoresizingMaskIntoConstraints = false
        webView.navigationDelegate = self
        webView.allowsBackForwardNavigationGestures = true
        webView.backgroundColor = .clear
        view.addSubview(webView)

        NSLayoutConstraint.activate([
            webView.topAnchor.constraint(equalTo: view.topAnchor),
            webView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
            webView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            webView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
        ])
        
        NSLayoutConstraint.activate([
            arscnView.topAnchor.constraint(equalTo: view.topAnchor),
            arscnView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
            arscnView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            arscnView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
        ])
    }
}

View hierarchy in xcode

This auto layout constraints looks well in a normal case with auto hiding/showing navigation bar and tool bar.

Normal case

However, at a specific webpage webview does not cover full screen. I found this phenomenon with aframe and I think this is due to <meta name='viewport' content='viewport-fit=cover'> (this tag automatically injected by aframe)

Abnormal case (when enter aframe page, the navigation bar and tool bar are automatically hidden)

I tried several solutions to handle this issue.

  1. set webView.scrollView.contentInsetAdjustmentBehavior = .never This looks good at a first glance, but I found that webview is obscured by navigation bar and tool bar

webview is obscured by navigation bar and tool bar

  1. The height of the white area in the bottom looks the summation of navigation bar and tool bar, so I tried to remove safe area when the bars are hidden by overriding safeAreaInsets of WKWebVIew.
class MyWebView: WKWebView {
    override var safeAreaInsets: UIEdgeInsets {
        var insets = UIEdgeInsets()
        
        insets.top = super.safeAreaInsets.top
        insets.bottom = super.safeAreaInsets.bottom
        insets.left = super.safeAreaInsets.left
        insets.right = super.safeAreaInsets.right
        
        // When navigation bar and tool bar are hidden
        if window?.safeAreaInsets == superview?.safeAreaInsets {
            insets.top = 0
            insets.bottom = 0
        }
        
        return UIEdgeInsets(top: insets.top, left: insets.left, bottom: insets.bottom, right: insets.right)
    }
}
...

//        webView = WKWebView(frame: .zero, configuration: config)
        webView = MyWebView(frame: .zero, configuration: config)

This still does not work.

  1. I tried set auto layout constraints at contentView of webView.scrollView
        // After setting constraints of WKWebView and ARSCNView
        NSLayoutConstraint.activate([
            webView.topAnchor.constraint(equalTo: view.topAnchor),
            webView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
            webView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            webView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
        ])
        ...
        
        // Get contentView of webView.scrollView
        guard let WKContentViewClass = NSClassFromString("WKContentView") else {
            print("Cannot find the WKContentView class")
            return
        }
        let WKContentViewClassName = NSStringFromClass(WKContentViewClass)
        guard let contentView = webView.scrollView.subviews.filter({ String(describing: type(of:$0)) == WKContentViewClassName }).first else {
            print("Cannot find the WKContentView instance")
            return
        }

        // Set auto layout constraints on contentView
        contentView.translatesAutoresizingMaskIntoConstraints = false
        contentView.layer.anchorPoint = CGPoint(x: 0.5, y: 0.5)

        NSLayoutConstraint.activate([
            contentView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
            contentView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
            contentView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
            contentView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
        ])

        ...

This still not works. This not change its height.

I got stuck this issue for weeks but still can not solve. Auto layout and safe area are too dizzy. How can I achieve the desired work of webview?

What I want to get is like this. the webview automatically adjust its position and height according to the navigation bar's transformation. And home indicator does not occupy any area.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
等待大神答复

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
...