8

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.

Miguel
  • 101
  • 2
  • 7

5 Answers5

3

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
}
msalandro
  • 31
  • 1
  • 3
2

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

Oliver
  • 599
  • 6
  • 14
  • Thanks for the help! I do have the Web View as the first view after Safe Area. I will look into your other suggestion! – Miguel Aug 06 '18 at 03:53
  • @Tobonaut isn’t it a working solution? What is your issue? – Oliver Feb 04 '19 at 18:37
  • 1
    @Oliver no it does not work. I've the same setup. My fix was (yeah, it's a bit hacky) to reset the content offset of the inner scrollview of the web view by using the scrollview delegate until the webview delegate raised the finished method. – Tobonaut Feb 05 '19 at 12:01
  • @Tobonaut I haven't found a fix yet. :( I resorted to removing the large titles and using the smaller centered ones instead. – Miguel May 24 '19 at 03:10
1

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)
    }
}
bompf
  • 1,374
  • 1
  • 18
  • 24
1

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.

FranG
  • 11
  • 1
0

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;
        }
    }
}
SAHM
  • 4,078
  • 7
  • 41
  • 77