Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are there any workaround to avoid SFSafariViewController from hiding fixed position headers?

SFSafariViewController has this bug that is not reproducible in Safari.

Regularly it will obscure the top of a fixed panel behind the site name / done chrome.

This happens cause internally it loses sync between actual height of the page and size of the shrinking header chrome.

Good small header

correct small header

Bad small header (SF chrome should be small but it is big)

sad

Good large header

correct big header

This issue was reported elsewhere at: https://meta.stackexchange.com/questions/279792/new-ios-chat-headers-occasionally-hide-behind-safari-navigation-controls-when-vi and is an issue in iOS 9 and up (still an issue in 12.0.1)

To reproduce make a dummy app with SFViewController and navigate to a site with a fixed header such as bbs.boingboing.net then click around and browse a few topics.

Since this bug is now a couple of years old I am wondering if there is some sort of workaround that does not involve adding a general padding to the top of the header?

Minimal repro

Make a page with this HTML

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
      body {
        height: 2000px;
        background-color: green;
      }
      header {
        width: 100%;
        height: 50px;
        background-color: red;
        color: white;
        position: fixed;
        top: 0;
      }
    </style>
  </head>
  <body>
    <header>Hello</header>
  </body>
</html>

Open in SafariViewController (host it somewhere online and then email a link, gmail app in iOS uses Safari View Controller, Discourse app as well)

Scroll quickly to the bottom

Half the header is hiding.

Insets make no difference inset for top is 0, cover viewport property makes no diff.

like image 705
Sam Saffron Avatar asked Oct 17 '18 06:10

Sam Saffron


1 Answers

- The Issue

Testing in different environments shows that the issue only appears in SFSafariView and the original safari app is not infected. And it's only appear in iPhone's with notch in portrait mode when user riches the end of the page and scroll again; So the page should go up and navigation bar automatically appears again and conflict will happen.

iPhone 8 iPhone 8 - Bottom of the page - Portrait (OK)

iPhone XR - Portrait iPhone XR - Bottom of the page - Portrait (NOT OK)

iPhone XR - Landscape iPhone XR - Bottom of the page - Portrait (OK)

iPad Pro 9.7 - Landscape iPad Pro 9.7 - Bottom of the page - Landscape (OK)

In some cases this may not be SFSafaryViewController's bug.

  • So if you have access to front-end developers of the site that you want to embed in the SFSafaryViewController, introduce the following to them:

- Safe Area Inset

Therefore to resolve this Apple implemented new safe-area-inset, pre-defined set of 4 constants and a new CSS function called constant(). The safe area pre-defined constants are as follows: safe-area-inset-top, safe-area-inset-right, safe-area-inset-bottom and save-area-inset-left. When you combine all four of those constants, you can reference the current size of safe area inset on each side. The constant() works everywhere a var() does.

There are a bunch of sites that show you how to adopt a web page to iPhone X. Here's one of them.

Maybe they could try placing the div outside of the scrollable part, and have the position fixed. So if you have a code where it scrolls:

<div id="scroll-container">
  <div id="scrollable">
  </div>
<div>

Such where any element in the div scroll-container, it will scroll.

If they place it outside of the scrollable part:

<div id="scroll-container">
<div>
<div id="not-scrollable">
</div>

and put position:fixed; or position:absolute; or position: sticky or device-fixed; or etc. in the css for #not-scrollable, It shouldn't scroll.

  • So if you don't have access to front-end developers of the site that you want to embed in the SFSafaryViewController try the following (Not recommended):

    • Try turning barCollapsing safaryViewController.configuration.barCollapsingEnabled = false
    • or Try embedding it in a navigationController and get rid of the SFView's header
    • or Use Implement a full screen WKWebView with controller instead of SFSafaryViewController.

Note (For those who mess with the toolbar)

  • You can use the delegate methods to determine the loading and loaded state of the web page and enable/disable it to get round the page layout initialization bug. (You can use manual delay too)
  • You can use private APIs to hide or show the bottom toolbar. But it's not preferred and it will reject from apple appstore.
like image 54
Mojtaba Hosseini Avatar answered Sep 27 '22 22:09

Mojtaba Hosseini