2

I'm trying to create an SwiftUI iOS app with a fullscreen WebView and having trouble with content going behind status bar. Eg with the following code:

import SwiftUI
import WebKit

struct ContentView: View {
    var body: some View {
        WebView(url: URL(string: "https://webkit.org"))
    }
}

When I load webkit.org (on an iPhone 15 Pro Max, iOS 26.0.1) the top of the page is obscured by the status bar and dynamic island. In contrast, Safari displays a solid color under the status bar and offsets the start of the page. When the user scrolls, Safari does allow the content to go under the status bar but there is a darkening effect which keeps the status bar readable.

App using WebKit on load Safari on load Safari after scrolling

Loading stackoverflow.com has a slightly different issue. On page load the content is correctly placed below the status bar but when the user scrolls the content appears below the status bar, above stackoverflow's menu bar. Safari doesn't have this issue.

App using WebKit on load App using WebKit after scrolling Safari after scrolling

How can I achieve similar behavior to Safari?

Ideally it would be identical but I would settle for the status bar being a solid color the whole time, hiding the content beneath.

I have experimented with applying:

  • .safeAreaPadding(.top)
  • .ignoresSafeArea([])

but these don't seem to have any impact.

1 Answer 1

2

I believe this is a bug. While scroll views are designed to extend beyond the safe area so that the content is not clipped at the edge of the safe area, their content should also be inset by the length of the safe area. The scroll view presenting the web content is apparently not insetting its content.

For now, I suggest just using SwiftUI Introspect to set contentInsets through the actual WKWebView.

WebView(url: URL(string: "https://webkit.org"))
    .introspect(.webView, on: .iOS(.v26)) { webView in
        webView.scrollView.contentInsetAdjustmentBehavior = .always
    }

If you are fine with the web view not extending beyond the safe area, you can also just add a tiny padding (at least one pixel) to the top of the web view,

@Environment(\.pixelLength) var onePixel

// ...

WebView(url: URL(string: "https://webkit.org"))
    .padding(.top, onePixel)
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you! The onePixel solution works nicely. With the introspect solution I find that webkit.org still loads with the top of the page obscured by the status bar although it now allows me to scroll down revealing the inset. Do you know how to make it load with the content inset?
@RobbieClarken Huh that's weird. I cannot reproduce that on iOS 26.0.1 simulator. Perhaps you can try setting contentOffset, or scrolling to the top edge in onAppear, using .webViewScrollPosition.
Actually it seems to be a bit nondeterministic for me on both device and in the simulator. Most of the time it loads with the status bar overlap (i.imgur.com/MAFSpPg.jpeg) although occasionally it loads with the page inset correctly (i.imgur.com/tIWmeMK.jpeg). Very strange! I'll experiment with contentOffset and webViewScrollPosition but I think the onPixel padding solution might be the safest option until the bug is fixed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.