Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

prefersLargeTtitles Collapses Automatically after Loading WKWebView Webpage

I'm having issues with Large Titles collapsing after a webpage in WKWebView finishes loading. Here is GIF example of what happens.

I've looked all over the internet and found two posts that might point in the right direction:

prefersLargeTitles not always honored - Apple Developer Forums

prefersLargeTitles - Displays correctly for a split second then collapses - Reddit

I would like the Large Titles to appear and remain in place when the webpage loads. When the user scrolls up (goes down on the webpage), the Large Titles should collapse to the smaller version. If the user goes back to the top of the webpage, the Large Titles should appear again.

Here's the code I have set up for a WKWebView:

import UIKit
import WebKit

class ViewController: UIViewController, WKUIDelegate {

    @IBOutlet weak var webView: WKWebView!

    override func viewDidLoad() {
        super.viewDidLoad()
        let myURL = URL(string: "https://www.apple.com")
        let myRequest = URLRequest(url: myURL!)
        webView.load(myRequest) 
    }
}

A point in the right direction would be greatly appreciated! Might it have something to do with scrollView.contentInsetAdjustmentBehavior?

Edit: Yes - I made sure Web View is the first view in Main.storyboard after Safe Area.

like image 641
Miguel Avatar asked Aug 04 '18 15:08

Miguel


3 Answers

I've run into the same issue and solved it using this workaround.

override func viewDidLoad() {
    webView.navigationDelegate = self
    webView.scrollView.contentInsetAdjustmentBehavior = .never
}

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    webView.scrollView.contentInsetAdjustmentBehavior = .automatic
}
like image 152
msalandro Avatar answered Oct 18 '22 00:10

msalandro


It usually happens when your scrollable view (UITableView, UICollectionView, UIWebView etc...) is not the first view.

Please check your view order in Main.storyboard. The appropriate order should be like this: 1- Safe Area 2 - your web view 3 - other views...

If it don't work, try to solve with scrollViewDidScroll method with changing the display mode of large navigation bar according to contentOffset.y

like image 28
Oliver Avatar answered Oct 18 '22 01:10

Oliver


I can offer a hack based off Tobonaut's suggestions:

class WebViewController: UIViewController {

    var webView: WKWebView!

    fileprivate var firstObservedOffset: CGFloat = 0

    override func viewDidLoad() {
        webView.scrollView.delegate = self
        webView.isHidden = true
    }

    // TODO: implement your loading mechanism

}

extension WebViewController: WKNavigationDelegate {
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        webView.scrollView.contentOffset = CGPoint(x: 0, y: firstObservedOffset)
    }
}

extension WebViewController: UIScrollViewDelegate {
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        let scrollView = self.webView.scrollView
        let yOffset = scrollView.contentOffset.y
        if yOffset != 0 && firstObservedOffset == 0 {
            firstObservedOffset = yOffset
            return
        }

        guard webView.isHidden
            && firstObservedOffset != 0
            && scrollView.contentOffset.y != firstObservedOffset else {
            return
        }

        scrollView.contentOffset = CGPoint(x: 0, y: firstObservedOffset)
    }
}
like image 45
bompf Avatar answered Oct 18 '22 00:10

bompf