Skip to content

Commit 7974eb4

Browse files
fix(ios): avoid app scrolling to top on keyboard hide (#533)
1 parent 27b9021 commit 7974eb4

File tree

1 file changed

+21
-28
lines changed

1 file changed

+21
-28
lines changed

src/ios/CDVWKWebViewEngine.m

Lines changed: 21 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,6 @@ @implementation CDVWKWebViewEngine
114114

115115
@synthesize engineWebView = _engineWebView;
116116

117-
NSTimer *timer;
118-
119117
- (instancetype)initWithFrame:(CGRect)frame
120118
{
121119
self = [super init];
@@ -311,15 +309,15 @@ - (void)pluginInitialize
311309
selector:@selector(onAppWillEnterForeground:)
312310
name:UIApplicationWillEnterForegroundNotification object:nil];
313311

314-
[[NSNotificationCenter defaultCenter]
315-
addObserver:self
316-
selector:@selector(keyboardWillHide)
317-
name:UIKeyboardWillHideNotification object:nil];
318-
319-
[[NSNotificationCenter defaultCenter]
320-
addObserver:self
321-
selector:@selector(keyboardWillShow)
322-
name:UIKeyboardWillShowNotification object:nil];
312+
// If less than ios 13.4
313+
if (@available(iOS 13.4, *)) {} else {
314+
// 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)
315+
// Apple has released a fix in 13.4, but not in 12.x (as of 12.4.6)
316+
[[NSNotificationCenter defaultCenter]
317+
addObserver:self
318+
selector:@selector(keyboardWillHide)
319+
name:UIKeyboardWillHideNotification object:nil];
320+
}
323321

324322
NSLog(@"Using Ionic WKWebView");
325323

@@ -386,27 +384,22 @@ - (void)onAppWillEnterForeground:(NSNotification *)notification {
386384

387385
-(void)keyboardWillHide
388386
{
389-
if (@available(iOS 12.0, *)) {
390-
timer = [NSTimer scheduledTimerWithTimeInterval:0 target:self selector:@selector(keyboardDisplacementFix) userInfo:nil repeats:false];
391-
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
392-
}
393-
}
387+
// 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)
388+
UIScrollView * scrollView = self.webView.scrollView;
389+
// Calculate some vars for convenience
390+
CGFloat contentLengthWithInsets = scrollView.contentSize.height + scrollView.adjustedContentInset.top + scrollView.adjustedContentInset.bottom;
391+
CGFloat contentOffsetY = scrollView.contentOffset.y;
392+
CGFloat screenHeight = scrollView.frame.size.height;
393+
CGFloat maxAllowedOffsetY = fmax(contentLengthWithInsets - screenHeight, 0); // 0 is for the case where content is shorter than screen
394394

395-
-(void)keyboardWillShow
396-
{
397-
if (timer != nil) {
398-
[timer invalidate];
395+
// If the keyboard allowed the user to get to an offset beyond the max
396+
if (contentOffsetY > maxAllowedOffsetY) {
397+
// Reset the scroll to the max allowed so that there is no additional empty white space at the bottom where the keyboard occupied!
398+
CGPoint bottomOfPage = CGPointMake(scrollView.contentOffset.x, maxAllowedOffsetY);
399+
[scrollView setContentOffset:bottomOfPage];
399400
}
400401
}
401402

402-
-(void)keyboardDisplacementFix
403-
{
404-
// https://stackoverflow.com/a/9637807/824966
405-
[UIView animateWithDuration:.25 animations:^{
406-
self.webView.scrollView.contentOffset = CGPointMake(0, 0);
407-
}];
408-
409-
}
410403
- (BOOL)shouldReloadWebView
411404
{
412405
WKWebView* wkWebView = (WKWebView*)_engineWebView;

0 commit comments

Comments
 (0)