prefersLargeTtitles Collapses Automatically after Loading WKWebView Webpage
Asked Answered
C

5

9

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.

Canto answered 4/8, 2018 at 15:19 Comment(1)
What did you end up doing to solve this?Hideandseek
C
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
}
Carbuncle answered 10/11, 2019 at 17:28 Comment(1)
This works 9 out of 10 times. :)Bimonthly
B
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

Backhand answered 5/8, 2018 at 1:3 Comment(4)
Thanks for the help! I do have the Web View as the first view after Safe Area. I will look into your other suggestion!Canto
@Tobonaut isn’t it a working solution? What is your issue?Backhand
@Backhand 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.Uralite
@Uralite I haven't found a fix yet. :( I resorted to removing the large titles and using the smaller centered ones instead.Canto
T
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)
    }
}
Trailer answered 8/2, 2019 at 11:37 Comment(0)
T
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.

Traumatize answered 10/5, 2020 at 18:11 Comment(1)
Wow, this actually worked for me, while all the other hacks didn't. Thanks!Eclogue
H
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;
        }
    }
}
Hideandseek answered 8/5, 2019 at 4:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.