Skip to content

Commit

Permalink
Fix window.innerHeight with WKWebView and shrinkView (#32) and proper…
Browse files Browse the repository at this point in the history
…ly remove observers
  • Loading branch information
cjpearson committed Aug 3, 2016
1 parent d123c78 commit 5583647
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 22 deletions.
12 changes: 4 additions & 8 deletions src/ios/CDVKeyboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,16 @@
#import <Cordova/CDVPlugin.h>

@interface CDVKeyboard : CDVPlugin {
@protected
BOOL _shrinkView;
@protected
BOOL _hideFormAccessoryBar;
@protected
id _keyboardShowObserver, _keyboardHideObserver, _keyboardWillShowObserver, _keyboardWillHideObserver;
@protected
id _shrinkViewKeyboardWillChangeFrameObserver;
}

@property (readwrite, assign) BOOL shrinkView;
@property (readwrite, assign) BOOL disableScrollingInShrinkView;
@property (readwrite, assign) BOOL hideFormAccessoryBar;
@property (readonly, assign) BOOL keyboardIsVisible;
@property (readwrite, assign, nonatomic) BOOL shrinkView;
@property (readwrite, assign, nonatomic) BOOL disableScrollingInShrinkView;
@property (readwrite, assign, nonatomic) BOOL hideFormAccessoryBar;
@property (readonly, assign, nonatomic) BOOL keyboardIsVisible;

- (void)shrinkView:(CDVInvokedUrlCommand*)command;
- (void)disableScrollingInShrinkView:(CDVInvokedUrlCommand*)command;
Expand Down
40 changes: 26 additions & 14 deletions src/ios/CDVKeyboard.m
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ - (void)pluginInitialize
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification* notification) {
[weakSelf performSelector:@selector(shrinkViewKeyboardWillChangeFrame:) withObject:notification afterDelay:0];
[weakSelf shrinkViewKeyboardWillChangeFrame:notification];
CGRect screen = [[UIScreen mainScreen] bounds];
CGRect keyboard = ((NSValue*)notification.userInfo[@"UIKeyboardFrameEndUserInfoKey"]).CGRectValue;
CGRect intersection = CGRectIntersection(screen, keyboard);
Expand All @@ -107,17 +107,12 @@ - (void)pluginInitialize

#pragma mark HideFormAccessoryBar

- (BOOL)hideFormAccessoryBar
{
return _hideFormAccessoryBar;
}

static IMP UIOriginalImp;
static IMP WKOriginalImp;

- (void)setHideFormAccessoryBar:(BOOL)ahideFormAccessoryBar
- (void)setHideFormAccessoryBar:(BOOL)hideFormAccessoryBar
{
if (ahideFormAccessoryBar == _hideFormAccessoryBar) {
if (hideFormAccessoryBar == _hideFormAccessoryBar) {
return;
}

Expand All @@ -127,7 +122,7 @@ - (void)setHideFormAccessoryBar:(BOOL)ahideFormAccessoryBar
Method UIMethod = class_getInstanceMethod(NSClassFromString(UIClassString), @selector(inputAccessoryView));
Method WKMethod = class_getInstanceMethod(NSClassFromString(WKClassString), @selector(inputAccessoryView));

if (ahideFormAccessoryBar) {
if (hideFormAccessoryBar) {
UIOriginalImp = method_getImplementation(UIMethod);
WKOriginalImp = method_getImplementation(WKMethod);

Expand All @@ -142,11 +137,27 @@ - (void)setHideFormAccessoryBar:(BOOL)ahideFormAccessoryBar
method_setImplementation(WKMethod, WKOriginalImp);
}

_hideFormAccessoryBar = ahideFormAccessoryBar;
_hideFormAccessoryBar = hideFormAccessoryBar;
}

#pragma mark KeyboardShrinksView

- (void)setShrinkView:(BOOL)shrinkView
{
// When the keyboard shows, WKWebView shrinks window.innerHeight. This isn't helpful when we are already shrinking the frame
// They removed this behavior is iOS 10, but for 8 and 9 we need to prevent the webview from listening on keyboard events
// Even if you later set shrinkView to false, the observers will not be added back
NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
if ([self.webView isKindOfClass:NSClassFromString(@"WKWebView")]
&& ![[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion){.majorVersion = 10, .minorVersion = 0, .patchVersion = 0 }]) {
[nc removeObserver:self.webView name:UIKeyboardWillHideNotification object:nil];
[nc removeObserver:self.webView name:UIKeyboardWillShowNotification object:nil];
[nc removeObserver:self.webView name:UIKeyboardWillChangeFrameNotification object:nil];
[nc removeObserver:self.webView name:UIKeyboardDidChangeFrameNotification object:nil];
}
_shrinkView = shrinkView;
}

- (void)shrinkViewKeyboardWillChangeFrame:(NSNotification*)notif
{
// No-op on iOS 7.0. It already resizes webview by default, and this plugin is causing layout issues
Expand Down Expand Up @@ -248,12 +259,13 @@ - (void)hide:(CDVInvokedUrlCommand*)command
- (void)dealloc
{
// since this is ARC, remove observers only

NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];

[nc removeObserver:self name:UIKeyboardWillShowNotification object:nil];
[nc removeObserver:self name:UIKeyboardWillHideNotification object:nil];
[nc removeObserver:self name:UIKeyboardWillChangeFrameNotification object:nil];
[nc removeObserver:_keyboardShowObserver];
[nc removeObserver:_keyboardHideObserver];
[nc removeObserver:_keyboardWillShowObserver];
[nc removeObserver:_keyboardWillHideObserver];
[nc removeObserver:_shrinkViewKeyboardWillChangeFrameObserver];
}

@end

0 comments on commit 5583647

Please sign in to comment.