Skip to content

fix(ios): avoid app scrolling to top on keyboard hide #533

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

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 21 additions & 28 deletions src/ios/CDVWKWebViewEngine.m
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,6 @@ @implementation CDVWKWebViewEngine

@synthesize engineWebView = _engineWebView;

NSTimer *timer;

- (instancetype)initWithFrame:(CGRect)frame
{
self = [super init];
Expand Down Expand Up @@ -303,15 +301,15 @@ - (void)pluginInitialize
selector:@selector(onAppWillEnterForeground:)
name:UIApplicationWillEnterForegroundNotification 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 less than ios 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");

Expand Down Expand Up @@ -378,27 +376,22 @@ - (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];
}
}
// 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

-(void)keyboardWillShow
{
if (timer != nil) {
[timer invalidate];
// 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);
}];

}
- (BOOL)shouldReloadWebView
{
WKWebView* wkWebView = (WKWebView*)_engineWebView;
Expand Down