futuretap/InAppSettingsKit

`WKWebView` in `IASKAppSettingsWebViewController` does not respect the Safe Area; it shows content behind the dynamic island

funnel20 opened this issue · 10 comments

When lading an URL, like https://www.apple.com, part of the webpage is shown behind the dynamic island and behind the navigation bar:
Simulator Screenshot - iPhone 15 Pro - 2024-09-20 at 20 46 10

*.plist content:

Screenshot 2024-09-20 at 20 46 49

As a work-around, I build my own UIViewController with:

  • a WKWebView
  • a UIProgressView
  • dynamic UIBarButtonItems for back and forward (meaning buttons are enabled/disabled whenever navigation is possible)
  • option to show it full screen over the tab bar

Simulator Screenshot - iPhone 15 Pro - 2024-09-27 at 11 01 25

@futuretap If you're interested in this WKWebView with more options, please let me know. Then I can either help you to extend the existing IASKAppSettingsWebViewController or add mine to the project.

I confirm the issue when loading https://www.apple.com. However, the problem does not occur for most other websites. Did you dig deeper what causes the issue?

In any case, I'd be more than happy to accept your help to fix IASKAppSettingsWebViewController. Having more options like a progress view and navigational buttons (back/forward/reload) would be useful. Unfortunately, the current calling mechanism using IASKViewControllerClass and IASKViewControllerSelector doesn’t really allow to specify parameters. I could imagine to introduce a dedicated IASKURL parameter for PSChildPaneSpecifier that directly opens a IASKAppSettingsWebViewController. Then we could add more boolean parameters like IASKWebViewShowProgress and IASKWebViewShowNavigationalButtons. What do you think?

The websites that I use did show the issue. For the issue report, I randomly picked Apple website, which also shows the issue. So for me that was reproducible enough. I didn't dig any deeper, but I suspect it is related to not properly respecting the safe layout margins.

Because I didn't want to expose the used URLs to the app user, I couldn't use SFSafariViewController. Hence I decided to built my own UIViewController around a WKWebView. It uses a *.xib file with all UI objects and layout constraints.

I was pleasantly surprised that I could use additional custom parameters using IASKViewControllerClass and IASKViewControllerSelector. So I specified a custom parameter url in the *.plist:

Screenshot 2024-09-27 at 11 58 09

And I can retrieve it in initWithFile:specifier: via specifier.specifierDict:

@implementation WebViewController

- (id)initWithFile:(NSString*)file specifier:(IASKSpecifier*)specifier {
    NSLog(@"urlString: %@", file);
    NSLog(@"specifier: %@", specifier);
    
    // Get additional properties from *.plist:
    if ((self = [super init])) {
        _url = [NSURL URLWithString:NSLocalizedString([specifier.specifierDict valueForKey:@"url"], nil)];
    }
    return self;
}

Of course it would be decent to introduce dedicated IASK... parameters.

Indeed, you can access the specifier to get the parameters. I forgot. So it’s probably fine to just extend IASKAppSettingsWebViewController. Using a XIB based approach is not ideal for a package/framework. Could you migrate it to code and integrate it into the existing code?

@futuretap Yes, I'm happy to extend IASKAppSettingsWebViewController programmatically with constraints.
As mentioned I'd like to add new IASK... parameters (the 4th was not named yet):

  1. IASKURL [string] - the URL to load
  2. IASKWebViewShowProgress [bool] - show a progress bar at the top of the WKWebView
  3. IASKWebViewShowNavigationalButtons [bool] - show dynamic back and forward buttons at the right side of the UINavigationItem
  4. IASKWebViewHideBottomBar [bool] - hide the toolbar at the bottom of the screen when the IASKAppSettingsWebViewController is pushed on to a navigation controller

For the 3 booleans, what should be the default value, when NOT specified in the *.plist?
I suggest to disable all, so when users update IASK, they will get the same look and feel as the current code of IASKAppSettingsWebViewController. They can add the parameters to their *.plist to get the new features.

Do you agree?

Current code is very old style, which is unaware of Safe Area:

self.webView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

I've replaced this by 4 proper anchor constraints to the safeAreaLayoutGuide and that resolves the main issue ✅

Simulator Screenshot - iPhone 15 Pro - 2024-09-27 at 16 24 15

I also noticed there is an UIActivityIndicatorView shown at the right side of the Navigation Bar, but it's set to UIActivityIndicatorViewStyleWhite, so not visible anymore since iOS 13 where the NavBar changed to white for Light color theme:

UIActivityIndicatorView *activityIndicatorView = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(0, 0, 40, 20)];
#if TARGET_OS_MACCATALYST || (defined(TARGET_OS_VISION) && TARGET_OS_VISION)
activityIndicatorView.activityIndicatorViewStyle = UIActivityIndicatorViewStyleMedium;
#else
activityIndicatorView.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhite;
#endif
[activityIndicatorView startAnimating];

Ik can change this to UIActivityIndicatorViewStyleGray as a fix. And when either IASKWebViewShowProgress or IASKWebViewShowNavigationalButtons is set ignore this UIActivityIndicatorView.

Do you agree?

Created new issue #504 because that's a feature request, while this issue relates to a bug.

@futuretap PR #505 is ready to resolve this bug(s)

Thanks, I agree with all your suggestions!

Just one thought: I think we should keep File instead of the additional IASKURL. Then it’s backwards compatible.