prefersLargeTtitles Collapses Automatically after Loading WKWebView Webpage

1k Views Asked by At

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.

5

There are 5 best solutions below

4
On

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

1
On

I've recently just encountered this problem myself and was able to address the issue by not using auto layout to position the web view in the larger view but used the autoresizing mask for the web view instead. Hope this helps someone.

1
On

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

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

The following worked for me (sorry it is in objective-C).

- (void)viewDidLoad {

    [super viewDidLoad];
    self.webView.navigationDelegate = self;
    self.webView.scrollView.delegate = self;
    self.webView.scrollView.scrollEnabled = YES;
    [_webView loadHTMLString:_htmlString baseURL:_baseURL];
}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {

    if (scrollView == _webView.scrollView) {
        if (_webView.isLoading) {
            [_webView.scrollView setContentOffset:CGPointMake(0, 0) animated:NO];
            return;
        }
    }
}