Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Add top notch detection #546

Closed
wants to merge 3 commits into from

Conversation

NiklasMerz
Copy link
Member

Platforms affected

iOS

Motivation and Context

This fixes an issue with iPhone that have a notch.

Closes #301

Description

Detect if phone has notch and adjust statusbar.

Testing

Using with iPhones with notch and without. Deployed to production app for some time.

Checklist

  • I've run the tests to see all new and existing tests pass
  • I added automated test coverage as appropriate for this change
  • Commit is prefixed with (platform) if this change only applies to one platform (e.g. (android))
  • If this Pull Request resolves an issue, I linked to the issue in the text above (and used the correct keyword to close issues using keywords)
  • I've updated the documentation if necessary

@NiklasMerz
Copy link
Member Author

@dpa99c Sorry for the ping and thanks for your reviews on my PRs, but I would like to add you as a reviewer. Probably someone should create a CODEROWNERS file with you, because you review PRs in this repo anyway :-D

@dpa99c
Copy link
Contributor

dpa99c commented Oct 5, 2019

Will try to get around to it shortly

@dpa99c
Copy link
Contributor

dpa99c commented Oct 15, 2019

@NiklasMerz Sorry for the delay. I've tested your branch used my test harness project.

It works fine if the IAB is opened while the device is in portrait orientation:

But if you orientate the device into landscape orientation before opening the IAB, the status bar height is incorrect in the IAB when it is opened. Instead of displaying no status bar, there's grey bar:

This then persists if you rotate the device back to portrait orientation:

@dpa99c
Copy link
Contributor

dpa99c commented Oct 15, 2019

I did start to make an attempt to detect the orientation change using the viewWillTransitionToSize delegate but didn't get much further than this initial attempt which didn't work:

- (void)viewWillAppear:(BOOL)animated
{
    if (IsAtLeastiOSVersion(@"7.0") && !viewRenderedAtLeastOnce) {
        viewRenderedAtLeastOnce = TRUE;
        [self setHeight];
        [[UIApplication sharedApplication] setStatusBarStyle:[self preferredStatusBarStyle]];
    }
    [self rePositionViews];
    
    [super viewWillAppear:animated];
}

-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
    [self setHeight];
}

-(void) setHeight
{
    CGRect mainStatusBarFrame = [UIApplication sharedApplication].statusBarFrame;
    CGFloat mainStatusBarFrameHeight = mainStatusBarFrame.size.height;
    CGRect statusBarFrame = [self getStatusBarFrame];
    statusBarFrame.size.height = mainStatusBarFrameHeight;
}

- (CGRect) getStatusBarFrame
{
    return [self invertFrameIfNeeded:[UIApplication sharedApplication].statusBarFrame];
}

I will try to make some time to look again but maybe this is some use to you in the meantime?

@NiklasMerz
Copy link
Member Author

NiklasMerz commented Oct 15, 2019 via email

@jcesarmobile
Copy link
Member

This is not a proper fix, it just hides the fake status bar for iPhone X and other devices with notches.

The proper fix should make the fake statusbar the size of the notch to be consistent, or just remove the fake statusbar for all devices.

@NiklasMerz
Copy link
Member Author

You are right. What about removing the statusbar for all devices? I think that would make sense. Does this mean we need an option to for showing/hiding the statusbar?

@NiklasMerz
Copy link
Member Author

The last two commits show my attempts to fix the statusbar heigth for devices with notch. But there is room for improvement. The statusbar looks kind of ugly on all devices and on devices in landscape mode, where it's empty. On devices with notch it is even bigger.

@jcesarmobile
Copy link
Member

I personally vote for removing it, it’s an ugly “hack” that doesn’t work well

@dpa99c
Copy link
Contributor

dpa99c commented Oct 16, 2019

I personally vote for removing it, it’s an ugly “hack” that doesn’t work well

I agree. Considering the effort required to make the statusbar work properly in the IAB for devices with a notch, removing it entirely is much easier and since the IAB is a secondary UI to the main Cordova app UI, not displaying the statusbar while it's open seems like a not-too-big inconvenience.

We could at least start by removing it entirely and if someone has time to make a PR which fixes display of the statusbar on all devices (notch and non-notch) in all orientations, with the additional option to display or not display it, then we can consider re-adding it at that point in time.

@jcesarmobile
Copy link
Member

Making it configurable is going to be troublesome as the toolbar is created in the CDVInAppBrowserNavigationController, where the InAppBrowser options are not available

@jcesarmobile
Copy link
Member

we are talking about the toolbar that is used as a fake status bar, not the real status bar, the status bar won't be hidden, but apple removed what used to be the solid status bar on iOS 7, so trying to keep that appearance of the iOS <= 6 status bar makes no sense anymore

@jcesarmobile
Copy link
Member

I understand, looks like you don’t.
You said that removing the status bar was not the solution, I told you we weren’t talking about the real status bar, but the fake status bar.
Now you say that InAppBrowser has ugly gray bars and that’s an issue.
That’s the fake status bar we are talking about and we are saying we should remove.

So you seem to agree with us

@jcesarmobile
Copy link
Member

Please, don’t try to rush things, we are all volunteers and we do what we can when we can and for free. Feel free to send the pull request yourself if you need it so much.

@NiklasMerz
Copy link
Member Author

I'm with @jcesarmobile . You need to be patient or do the fix yourself. That's how I do things. That's how it works in Open Source. We cannot expect anyone to do the work just because we feel the need for us and others.

I am currently happy with the solution as it is in this PR. I may do the complete removal of the statusbar some time in the future if I have the spare time, but let's see.

@mosababubakr Just try doing this change yourself. It is not that hard as you might expect. I never worked on native iOS projects before, but I did some contributions to iOS Cordova plugins just by trying stuff out and googling. You may find a solution and can get feedback on a PR to get it working as you like.

@brody4hire brody4hire changed the title Add top notch detection [WIP] Add top notch detection Oct 23, 2019
@brody4hire
Copy link

Hi @NiklasMerz I took the liberty to add "[WIP]" to the title since this PR seems to be not ready for us to review and merge right now. (I would really favor I would also wonder if this might be solved by https://github.com/EddyVerbruggen/cordova-plugin-safariviewcontroller or by the https://github.com/toontoet/cordova-plugin-themeablebrowser fork that was mentioned in #301 (comment)?

I would also favor getting rid of the status bar, let other forks do something more elaborate if needed.

@NiklasMerz
Copy link
Member Author

That's fine. I can try to do the removal of the fake statusbar, if I find time anytime soon, to update this PR. Removing the statusbar seems logical.

@mosabab
Copy link
Contributor

mosabab commented Nov 18, 2019

That's fine. I can try to do the removal of the fake statusbar, if I find time anytime soon, to update this PR. Removing the statusbar seems logical.

You are right,

I test your fork modified plugin, and work well in portrait mode, but in landscape mode the empty grey bar appear, I think removing it could be better.

@mosabab
Copy link
Contributor

mosabab commented Jan 6, 2020

@NiklasMerz
When you think this pull could be done ?

I think it could be better to merge your fix to the 3.2.0 release make good sense.

@NiklasMerz
Copy link
Member Author

No this one is not ready. It works for me and might work for you but it is not a proper fix and won't be in 3.2.0

Like suggested by jcesarmobile a proper fix would be to remove the "fake statusbar" completely in the next major release. I looked at this briefly and I am afraid I don't know enough about Objective-C to do this in the time I have available. I created #604 for that and others might pick this up.

@justjoeyuk
Copy link

@jcesarmobile I'm using Ionic 4 and Capacitor (I know this is specific to in-app-browser). However, is there anyway I can use the in-app-browser Cordova plugin with my own custom changes in Capacitor? Can't find any way to do that.

@brody4hire
Copy link

@justjoeyuk and others please feel free to fork and adapt.

@NiklasMerz NiklasMerz mentioned this pull request Feb 22, 2020
5 tasks
@sardapv
Copy link

sardapv commented Apr 6, 2020

I did little change in plugin to detect and Resize InAppBrowser based on Notched devices. It adjusts its dimensions to fit safe area with orientation change as well . PS: I am not a swift or Pro apple coder, but took lot of time to get it fixed for my use case. Any contributor is free to modify below code, might be ugly. Have not tested this with that Done button pane for IAB, for my use case of hybird app which uses full screen no URL bar, this worked.

Change in CDVInAppBrowserNavigationController.m

statusBarFrame.size.height = 0;

Change in CDVWKInAppBrowser.m

declare -

float orgHeight = 0;
float orgWidth = 0;

add these 2 methods-

- (BOOL)hasTopNotch { // method returns true if notch is at top
    if (@available(iOS 11.0, *)) {
        if([[[UIApplication sharedApplication] delegate] window].safeAreaInsets.top>20.0){
            return YES;
        }
    }
    return  NO;
}

- (BOOL)hasLeftOrRightNotch { //method returns true if notch is at left or right side
    if (@available(iOS 11.0, *)) {
        if([[[UIApplication sharedApplication] delegate] window].safeAreaInsets.left>20.0){
            return YES;
        }
        if([[[UIApplication sharedApplication] delegate] window].safeAreaInsets.right>20.0){
            return YES;
        }
    }
    return  NO;
}

Modify ViewWillAppear to

- (void)viewWillAppear:(BOOL)animated

{
    if (IsAtLeastiOSVersion(@"7.0") && !viewRenderedAtLeastOnce) { // set origin based on notch and safe area
        viewRenderedAtLeastOnce = TRUE;
        CGRect viewBounds = [self.webView bounds];
        if ([self hasTopNotch]) {
            float topSafeArea = [[[UIApplication sharedApplication] delegate] window].safeAreaInsets.top;
            viewBounds.origin.y = topSafeArea;
        } else if ([self hasLeftOrRightNotch]) {
            float leftSafeArea = [[[UIApplication sharedApplication] delegate] window].safeAreaInsets.left;
            viewBounds.origin.x = leftSafeArea;
        } else {
            viewBounds.origin.y = STATUSBAR_HEIGHT;
            viewBounds.size.height = viewBounds.size.height - STATUSBAR_HEIGHT;
        }
        self.webView.frame = viewBounds;
        [[UIApplication sharedApplication] setStatusBarStyle:[self preferredStatusBarStyle]];
    }
    [self rePositionViews];
    [super viewWillAppear:animated];
}

Modify to supportedInterfaceOrientations method to

- (NSUInteger)supportedInterfaceOrientations
{
    if ((self.orientationDelegate != nil) && [self.orientationDelegate respondsToSelector:@selector(supportedInterfaceOrientations)]) {
        CGRect viewBounds = [self.webView bounds];
            if (orgWidth == 0 && orgHeight == 0) { //set height and width on launch 
                if ([self hasTopNotch]) { //when app is launched in portrait mode, set hight excluding safe area
                    float topSafeArea = [[[UIApplication sharedApplication] delegate] window].safeAreaInsets.top;
                    orgHeight = viewBounds.size.height - (topSafeArea);
                    orgWidth = viewBounds.size.width;
                } else { //when app is launched in landscape mode, set width excluding safe area
                    float leftSafeArea = [[[UIApplication sharedApplication] delegate] window].safeAreaInsets.left;
                    orgHeight = viewBounds.size.height;
                    orgWidth = viewBounds.size.width - (2*leftSafeArea);
                }
            } else if ([self hasTopNotch] && viewRenderedAtLeastOnce) { //on oritentation change, swap dimensions assuming safe area
                float topSafeArea = [[[UIApplication sharedApplication] delegate] window].safeAreaInsets.top;
                viewBounds.origin.y = topSafeArea;
                if(viewBounds.size.height == orgWidth) { //this block is when landscape to portrait is changed
                    viewBounds.size.height = orgWidth;
                    viewBounds.size.width = orgHeight;
                } else {
                    viewBounds.size.height = orgHeight;
                    viewBounds.size.width = orgWidth;
                }
            } else if ([self hasLeftOrRightNotch] && viewRenderedAtLeastOnce) {
                float leftSafeArea = [[[UIApplication sharedApplication] delegate] window].safeAreaInsets.left;
                viewBounds.origin.x = leftSafeArea;
                if(viewBounds.size.width == orgHeight) { //this block is when portrait to landscape is changed
                    viewBounds.size.height = orgWidth;
                    viewBounds.size.width = orgHeight;
                } else {  // special case of oritention change from portrait to landscaoe both left and right direction
                    viewBounds.size.width = orgHeight - leftSafeArea;
                    viewBounds.size.height = orgWidth;
                }
            } else { //for non notched devices
                viewBounds.origin.y = STATUSBAR_HEIGHT;
                viewBounds.size.height = orgHeight;
            }
        self.webView.frame = viewBounds;
        [self rePositionViews];
        
        return [self.orientationDelegate supportedInterfaceOrientations];
    }

@NiklasMerz
Copy link
Member Author

Should be solved with #604 which is the proper solution

@NiklasMerz NiklasMerz closed this Apr 6, 2020
rufiange pushed a commit to jalios/cordova-plugin-inappbrowser that referenced this pull request Apr 7, 2020
@NiklasMerz NiklasMerz deleted the topnotch branch November 30, 2020 13:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Issue with status bar on iPhone X when toolbar is at the top (v3.0.0)
7 participants