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

Keyboard Dismissal Leaves Viewport Shifted in iOS 12 / XCode 10 #176

Closed
Stefano1964 opened this issue Sep 22, 2018 · 14 comments · Fixed by #201
Closed

Keyboard Dismissal Leaves Viewport Shifted in iOS 12 / XCode 10 #176

Stefano1964 opened this issue Sep 22, 2018 · 14 comments · Fixed by #201

Comments

@Stefano1964
Copy link

Stefano1964 commented Sep 22, 2018

I think it's a bug in ionic plugin (without the cordova-plugin-ionic-keyboard installed):
apache/cordova-ios#417

@Stefano1964
Copy link
Author

I have find why, in:
https://github.com/ionic-team/cordova-plugin-ionic-webview/blob/master/src/ios/CDVWKWebViewEngine.m
change line 38, 308 with
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 && __IPHONE_OS_VERSION_MAX_ALLOWED < 120000
it's a bug in iOS 11 not in iOS 12, so running with iOS 12 the webview is not scrolled back to original position when keyboard is dismissed, line 79 and 310.

@Stefano1964
Copy link
Author

If you want to check also iPad (and this why on iPad was working with iOS 12 and mybe not working with iOS 11)
#if (__IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 && __IPHONE_OS_VERSION_MAX_ALLOWED < 120000) || (__IPAD_OS_VERSION_MAX_ALLOWED >= 110000 && __IPAD_OS_VERSION_MAX_ALLOWED < 120000)

@joeldhenry
Copy link

Thanks so much @Stefano1964! I just discovered this pretty catastrophic bug today! I second your merge proposal 👍

@mobidev111
Copy link

please create a PR

@revie
Copy link

revie commented Sep 27, 2018

The fix breaks the display in iPhone X and later models (XR, XS, and XS Max) for those that are using Ionic, where the extra spacing initially complained about when the keyboard disappears now becomes an issue as soon as the app is opened. The fix is an easy CSS change, at least for Ionic v1 apps:

.view, .view-container { height: calc(100% + env(safe-area-inset-top) + env(save-area-inset-bottom); }

At least it's now obvious where the extra spacing is coming from.

@booleanbetrayal
Copy link
Contributor

I am also witnessing the initial offset that the referenced patch creates in iPhoneX variants and can verify that @revie 's CSS tweak (applied to html element in our case) remedies that. However I'm not seeing the displacement fix actually work. Seems to have no effect on our app, leaving the viewport permanently offset after keyboard dismissal.

@jkervine
Copy link

jkervine commented Oct 4, 2018

Hi, I tried multiple things to get this fixed, including the CDVWKWebViewEngine.m thing above and tweaking options to the cordova-plugin-ionic-keyboard among other things. Finally, the only thing that helped was to download XCode 9.4, add iOS 12 device profiles and build using that version. According to initial testing, this seems to work on iOS 12 devices also on iPhone X.

@TylerAHolden
Copy link

Changing CDVWKWebViewEngine.m worked for me except now the entire window height was off as mentioned above. The css for .view did not help, instead I did html { height: 100vh; } to solve the issue. BUT now platform.height() responds with the original height (which is of course incorrect)... It seems my hacky fix has just led to more issues. This is a pretty critical bug imo.. anyone else experiencing this or have a fix?

@jcesarmobile
Copy link
Member

I've created a sample project with the bug https://github.com/jcesarmobile/webview-input-bug

It's a tabs project with an ion-input and a regular input. The bug is only reproducible when clicking the regular input, the ion-input internally manages the repositioning to avoid this kind of bugs.

This is a WKWebView bug on SDK 12, so the real fix can only be provided by Apple, or use some workaround, those are the options:

  1. Wait for Apple to fix it in a future release, it's already reported.
  2. Use Xcode 9 for now as it will use SDK 11 to compile and the bug is not present there.
  3. Use ion-input instead of regular input (only applicable if using Ionic)
  4. Install cordova-plugin-ionic-keyboard, any preference seems good in my sample as long as the plugin is installed. (might not work in non Ionic projects, didn't test there)

If not using Ionic and you think the linked PR fixes the problem there, provide a sample app. I've tested the PR changes in my project and didn't fix the problem.

@booleanbetrayal
Copy link
Contributor

booleanbetrayal commented Oct 25, 2018

Could use some testing on the above PR (#201) ^

cordova plugin add https://github.com/booleanbetrayal/cordova-plugin-ionic-webview.git#fix_ios_12_viewport

/cc @mobidev111 @jcesarmobile @NG-tylerholden @jkervine

@vuthanhict
Copy link


 if #available(iOS 11.0, *) {
             self.webView.scrollView.contentInsetAdjustmentBehavior = .never
 } else {
            self.automaticallyAdjustsScrollViewInsets = false
 }

And UIScrollViewDelegate

 func scrollViewDidChangeAdjustedContentInset(_ scrollView: UIScrollView) {
       Logger.print("scrollViewDidChangeAdjustedContentInset")
         if #available(iOS 12.0, *) {
           for view in webView.subviews {
                if let scrollView = view as? UIScrollView {
                   scrollView.setContentOffset(.zero, animated: true)
                 }
             }
        }
}

Worked

@sooheesh
Copy link

sooheesh commented Jan 17, 2019

This did work for me.

ViewController.h

@property (nonatomic) CGPoint lastContentOffset;

ViewController.m

- (void)viewDidLoad {    
        [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(onKeyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
        [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(onKeyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
}
- (void)onKeyboardWillShow:(NSNotification *)notification {
    self.lastContentOffset = self.webView.scrollView.contentOffset;
}
- (void)onKeyboardWillHide:(NSNotification *)notification {
    if (!CGPointEqualToPoint(self.lastContentOffset, self.webView.scrollView.contentOffset)) {
        [self.webView.scrollView setContentOffset:self.lastContentOffset];
        [self.webView.scrollView setContentInset:UIEdgeInsetsMake(0, 0, 0, 0)];
    }
     if (!CGPointEqualToPoint(self.lastContentOffset, self.webView.scrollView.contentOffset)) {
        [self.webView.scrollView setContentOffset:self.lastContentOffset];
        [self.webView.scrollView setContentInset:UIEdgeInsetsMake(0, 0, 0, 0)];
    }
}

@MiqueiasMaia
Copy link

MiqueiasMaia commented Jan 14, 2020

I solve this bug with these command lines on app.components.ts:

let html = document.getElementsByTagName("html")[0];

 window.addEventListener('native.keyboardshow', (e) => {
      console.log("show2");
      html.style.height = "auto";
  });
window.addEventListener('native.keyboardhide', () => {
      console.log("hide2");
      html.style.height = "101vh";
});

@sajallimbu
Copy link

This did work for me.

ViewController.h

@property (nonatomic) CGPoint lastContentOffset;

ViewController.m

- (void)viewDidLoad {    
        [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(onKeyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
        [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(onKeyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
}
- (void)onKeyboardWillShow:(NSNotification *)notification {
    self.lastContentOffset = self.webView.scrollView.contentOffset;
}
- (void)onKeyboardWillHide:(NSNotification *)notification {
    if (!CGPointEqualToPoint(self.lastContentOffset, self.webView.scrollView.contentOffset)) {
        [self.webView.scrollView setContentOffset:self.lastContentOffset];
        [self.webView.scrollView setContentInset:UIEdgeInsetsMake(0, 0, 0, 0)];
    }
     if (!CGPointEqualToPoint(self.lastContentOffset, self.webView.scrollView.contentOffset)) {
        [self.webView.scrollView setContentOffset:self.lastContentOffset];
        [self.webView.scrollView setContentInset:UIEdgeInsetsMake(0, 0, 0, 0)];
    }
}

Which ViewController.h and .m are you referring to? I dont see such files inside my cordova project folder. Also, just changing the keyboardwillhide and keyboardwillshow methods in CDVWKWebviewEngine inside the ionic-wk-webview-plugin files did fix the problem for ios13 but causes the viewport to have a bounce effect on ios 12 when shifting focus between text fields.

Lindsay-Needs-Sleep added a commit to miloproductionsinc/cordova-plugin-ionic-webview that referenced this issue Mar 21, 2020
…#176) (ionic-team#399)

- We only need the KeyboardWillHide event to fix this problem, and we only need it for ios 11+
- Enable the fix for ios 11+, not only ios 12+. It was probably only 12+ becase no devices have a max OS of 11, so no dev probably confirmed the problem's existance (or non-existance) on 11, myself included.  (But the functionality that started this issue chain began in ios 11.)
- Do some math to make sure the offset when the keyboard goes down dosen't result in empty white space being displayed.
- This solution can potentially be removed when apple finally releases the fix for the issue discussed here: apache/cordova-ios#417 (comment))
Lindsay-Needs-Sleep added a commit to miloproductionsinc/cordova-plugin-ionic-webview that referenced this issue Mar 21, 2020
…#176) (ionic-team#399)

- We only need the KeyboardWillHide event to fix this problem
- Do some math to make sure the offset when the keyboard goes down doesn't result in empty white space being displayed.
- This solution can potentially be removed when apple finally releases the fix for the issue discussed here: apache/cordova-ios#417 (comment)
Lindsay-Needs-Sleep added a commit to miloproductionsinc/cordova-plugin-ionic-webview that referenced this issue Mar 21, 2020
…#176) (ionic-team#399)

- We only need the KeyboardWillHide event to fix this problem, and we only need it for ios 11+
- Enable the fix for ios 11+, not only ios 12+. It was probably only 12+ because no devices have a max OS of 11, so no dev probably confirmed the problem's existence (or non-existence) on 11, myself included.  (But the functionality that started this issue chain began in ios 11.)
- Do some math to make sure the offset when the keyboard goes down doesn't result in empty white space being displayed.
- This solution can potentially be removed when apple finally releases the fix for the issue discussed here: apache/cordova-ios#417 (comment)
Lindsay-Needs-Sleep added a commit to miloproductionsinc/cordova-plugin-ionic-webview that referenced this issue Mar 23, 2020
…#176) (ionic-team#399)

- We only need the KeyboardWillHide event to fix this problem, and we only need it for ios 11+
- Enable the fix for ios 11+, not only ios 12+. It was probably only 12+ because no devices have a max OS of 11, so no dev probably confirmed the problem's existence (or non-existence) on 11, myself included.  (But the functionality that started this issue chain began in ios 11.)
- Do some math to make sure the offset when the keyboard goes down doesn't result in empty white space being displayed.
- This solution can potentially be removed when apple finally releases the fix for the issue discussed here: apache/cordova-ios#417 (comment)
For full details see PR ionic-team#532
Lindsay-Needs-Sleep added a commit to miloproductionsinc/cordova-plugin-ionic-webview that referenced this issue Mar 23, 2020
…#176) (ionic-team#399)

- We only need the KeyboardWillHide event to fix this problem
- Do some math to make sure the offset when the keyboard goes down doesn't result in empty white space being displayed.
- This solution can potentially be removed when apple finally releases the fix for the issue discussed here: apache/cordova-ios#417 (comment)
For full details see PR ionic-team#533
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 a pull request may close this issue.