From d82b0f38f6111dbcde32e1a823d225176288507e Mon Sep 17 00:00:00 2001 From: Lindsay-Needs-Sleep Date: Sat, 21 Mar 2020 04:05:56 -0600 Subject: [PATCH 1/2] fix(iOS): Fix scroll issues related to keyboard dismissal (#176) (#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: https://github.com/apache/cordova-ios/issues/417#issuecomment-423340885 For full details see PR #532 --- src/ios/CDVWKWebViewEngine.m | 54 +++++++++++++++--------------------- 1 file changed, 22 insertions(+), 32 deletions(-) diff --git a/src/ios/CDVWKWebViewEngine.m b/src/ios/CDVWKWebViewEngine.m index 0c949731..51a8cc9e 100644 --- a/src/ios/CDVWKWebViewEngine.m +++ b/src/ios/CDVWKWebViewEngine.m @@ -127,8 +127,6 @@ @implementation CDVWKWebViewEngine @synthesize engineWebView = _engineWebView; -NSTimer *timer; - - (instancetype)initWithFrame:(CGRect)frame { self = [super init]; @@ -410,16 +408,13 @@ - (void)pluginInitialize selector:@selector(onSocketError:) name:@"socketInUseError" object:nil]; - [[NSNotificationCenter defaultCenter] - addObserver:self - selector:@selector(keyboardWillHide) - name:UIKeyboardWillHideNotification object:nil]; - - [[NSNotificationCenter defaultCenter] - addObserver:self - selector:@selector(keyboardWillShow) - name:UIKeyboardWillShowNotification object:nil]; - + if (@available(iOS 11.0, *)) { + // For keyboard dismissal leaving viewport shifted (can potentially be removed when apple releases the fix for the issue discussed here: https://github.com/apache/cordova-ios/issues/417#issuecomment-423340885) + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(keyboardWillHide) + name:UIKeyboardWillHideNotification object:nil]; + } NSLog(@"Using Ionic WKWebView"); @@ -531,31 +526,26 @@ - (void)onAppWillEnterForeground:(NSNotification *)notification { } } - -(void)keyboardWillHide { - if (@available(iOS 12.0, *)) { - timer = [NSTimer scheduledTimerWithTimeInterval:0 target:self selector:@selector(keyboardDisplacementFix) userInfo:nil repeats:false]; - [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; - } -} - --(void)keyboardWillShow -{ - if (timer != nil) { - [timer invalidate]; + if (@available(iOS 11.0, *)) { + // For keyboard dismissal leaving viewport shifted (can potentially be removed when apple releases the fix for the issue discussed here: https://github.com/apache/cordova-ios/issues/417#issuecomment-423340885) + UIScrollView * scrollView = self.webView.scrollView; + // Calculate some vars for convenience + CGFloat contentLengthWithInsets = scrollView.contentSize.height + scrollView.adjustedContentInset.top + scrollView.adjustedContentInset.bottom; + CGFloat contentOffsetY = scrollView.contentOffset.y; + CGFloat screenHeight = scrollView.frame.size.height; + CGFloat maxAllowedOffsetY = fmax(contentLengthWithInsets - screenHeight, 0); // 0 is for the case where content is shorter than screen + + // If the keyboard allowed the user to get to an offset beyond the max + if (contentOffsetY > maxAllowedOffsetY) { + // Reset the scroll to the max allowed so that there is no additional empty white space at the bottom where the keyboard occupied! + CGPoint bottomOfPage = CGPointMake(scrollView.contentOffset.x, maxAllowedOffsetY); + [scrollView setContentOffset:bottomOfPage]; + } } } --(void)keyboardDisplacementFix -{ - // https://stackoverflow.com/a/9637807/824966 - [UIView animateWithDuration:.25 animations:^{ - self.webView.scrollView.contentOffset = CGPointMake(0, 0); - }]; - -} - - (void)onSocketError:(NSNotification *)notification { [self loadErrorPage:nil]; } From e1a7e37a780c8649e9aafca9befa3b7a05489aa1 Mon Sep 17 00:00:00 2001 From: Lindsay-Needs-Sleep Date: Fri, 27 Mar 2020 04:37:35 -0600 Subject: [PATCH 2/2] (ios) Limit the keyboard dismissal bug fix to ios [11.0, 13.4) because in ios 13.4 Apple fixed the problem. See https://github.com/ionic-team/cordova-plugin-ionic-webview/pull/533#issuecomment-604924818 --- src/ios/CDVWKWebViewEngine.m | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/ios/CDVWKWebViewEngine.m b/src/ios/CDVWKWebViewEngine.m index 51a8cc9e..4b1167b5 100644 --- a/src/ios/CDVWKWebViewEngine.m +++ b/src/ios/CDVWKWebViewEngine.m @@ -408,12 +408,18 @@ - (void)pluginInitialize selector:@selector(onSocketError:) name:@"socketInUseError" object:nil]; + // If greater than 11 if (@available(iOS 11.0, *)) { - // For keyboard dismissal leaving viewport shifted (can potentially be removed when apple releases the fix for the issue discussed here: https://github.com/apache/cordova-ios/issues/417#issuecomment-423340885) - [[NSNotificationCenter defaultCenter] - addObserver:self - selector:@selector(keyboardWillHide) - name:UIKeyboardWillHideNotification object:nil]; + // And less than 13.4 + if (@available(iOS 13.4, *)) {} else { + // For keyboard dismissal leaving viewport shifted + // Can potentially be removed when apple releases the fix for the issue discussed here: https://github.com/apache/cordova-ios/issues/417#issuecomment-423340885 + // Apple has released a fix in 13.4, but not in 12.x (as of 12.4.6) + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(keyboardWillHide) + name:UIKeyboardWillHideNotification object:nil]; + } } NSLog(@"Using Ionic WKWebView");