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

cordova.plugins.Keyboard does not working #27

Closed
robaweb opened this issue Dec 5, 2014 · 38 comments

Comments

@robaweb
Copy link

@robaweb robaweb commented Dec 5, 2014

Hi!
cordova.plugins.Keyboard.hideKeyboardAccessoryBar and cordova.plugins.Keyboard.disableScroll have not effect :( For ionic keyboard plugin it's same issue too.
Tested on iOS sdk 8.1, cordova 3.7.0 and 3.6.x, org.cordova.plugins.keyboard latest version. Also i tried use latest org.cordova.plugins.labs.keyboard and steel not working.
Without WKWebView all is fine.
Is it possible to fix it?

@geppy

This comment has been minimized.

Copy link
Contributor

@geppy geppy commented Dec 17, 2014

WkWebView doesn't seem to have an equivalent of UIWebView's keyboardDisplayRequiresUserAction.

@robaweb

This comment has been minimized.

Copy link
Author

@robaweb robaweb commented Dec 17, 2014

Is there way to disable scrolling view when keyboard is open? Most common for mobile apps is fixed view or shrinked view with opened keyboard, but not scrolled over top of mobile screen.

@EddyVerbruggen

This comment has been minimized.

Copy link
Member

@EddyVerbruggen EddyVerbruggen commented Dec 18, 2014

Hi @robaweb,

If you want this as a feature for your app and you're using XCode, then you could do something like this to disable scroll when the keyboard is shown:

MyMainViewController.m, method init, add this before return self:

  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:)
                                               name:UIKeyboardDidShowNotification object:nil];

And add this method to the same class:

- (void)keyboardDidShow: (NSNotification *) notif {
  self.wkWebView.scrollView.scrollEnabled = NO;
}

In the same way you could re-enable scrolling when the keyboard is hidden.

It would be possible to use this same approach to sync this with the Ionic keyboard plugin, but as that may not be necessary I won't elaborate on that.

@geppy

This comment has been minimized.

Copy link
Contributor

@geppy geppy commented Dec 18, 2014

@EddyVerbruggen That doesn't seem to work in my app (the view is still scrolled).

@runspired

This comment has been minimized.

Copy link

@runspired runspired commented Feb 9, 2015

+1

1 similar comment
@robaweb

This comment has been minimized.

Copy link
Author

@robaweb robaweb commented Feb 28, 2015

+1

@admmasters

This comment has been minimized.

Copy link

@admmasters admmasters commented Apr 11, 2015

+1 Really would like a fix for this.

@Wenape

This comment has been minimized.

Copy link

@Wenape Wenape commented May 3, 2015

+1

1 similar comment
@hussfelt

This comment has been minimized.

Copy link

@hussfelt hussfelt commented May 15, 2015

+1

@EddyVerbruggen

This comment has been minimized.

Copy link
Member

@EddyVerbruggen EddyVerbruggen commented May 15, 2015

Played with this a bit more. Bad news, but feel free to poke at this as well:

  • hideKeyboardAccessoryBar: can't find a way to remove the accessory bar.
  • disableScroll: you can disabled scrolling the webview while the keyboard is open (if ppl want that, let me know!), but I have not yet found a way to disable the scroll that is performed during the opening of the keyboard (the keyboard pushes the webview up).
@Wenape

This comment has been minimized.

Copy link

@Wenape Wenape commented Jun 3, 2015

Using self.wkWebView.scrollView.scrollEnabled = NO disables scrolling, but only for user initiated gestures. The keyboard can still scroll the wkWebView. With the normal webview this didn't happen, setting scrollEnabled to 'NO' would prevent even the keyboard from scrolling the webview.

Using self.wkWebView.scrollView.scrollEnabled = NO still helps as it prevent further scrolling triggered by the user when the keyboard is already in view. The actual problem is the keyboard scrolling the wkWebView about 20px to the left.

A fix for this is to use:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onKeyboardShow:) name:UIKeyboardWillShowNotification object:nil];


- (void)onKeyboardShow: (NSNotification *) notif {
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.01 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
        self.wkWebView.scrollView.contentOffset = CGPointMake(0, 0);
    });
}

This scrolls the webview back to the center after the keyboard scrolls the webview to the left. This is not a clean fix though, you can still see a slight change happening.

@rumit91

This comment has been minimized.

Copy link
Contributor

@rumit91 rumit91 commented Jun 23, 2015

+1 I'm also hitting this issue.

My team was interested in using the WKWebView in iOS8 because the UIWebView had some rendering issues with our content. However, being able to control the keyboard behavior is pretty critical to making the webview feel like an app, so this issue is a major blocker.

I was able to get a partial fix working with the cordova-plugin-keyboard. The following changes will cause the webview to shrink appropriately when the keyboard comes up. However, when the user begins typing the webview's internal UIScrollView will again offset incorrectly.

I created the following method in ReroutingUIWebView.m (and added the method signature to the header file):

- (void)changeFrame:(CGRect)newFrame {
    self.wkWebView.frame = newFrame;

    // Setting the content of the scrollView to the same size and offset as the frame.
    [self.wkWebView.scrollView setContentOffset:CGPointMake(0.0, 0.0) animated: false];
    [self.wkWebView.scrollView setContentSize:CGSizeMake(newFrame.size.width, newFrame.size.height)];
}

Then in CDVKeyboard.m of the cordova-plugin-keyboard I added the following line to the end of the shrinkViewKeyboardWillChangeFrame method.

[((ReroutingUIWebView*)self.webView) changeFrame:[self.webView.superview convertRect:screen fromView:self.webView]];

This requires an #import "ReroutingUIWebView.h" at the top of CDVKeyboard.m which is pretty ugly since it introduces a dependency between the two plugins. Like I said earlier, this also does not prevent the scrollview from initiating the offset that pushes the webview up whenever the user starts typing. The default webview scrollview is being too 'helpful' in trying to make sure that the input field is in view for the user. As @EddyVerbruggen said disabling scrolling in the webview doesn't help either since that only controls user initiated scrolling.

If you have any ideas on how to fix this issue, please let me know!

@EddyVerbruggen

This comment has been minimized.

Copy link
Member

@EddyVerbruggen EddyVerbruggen commented Jun 24, 2015

@rumit91, @Wenape Do you guys have a demo project showing off the error? If I create something with the Cordova CLI I feel like it's not the same trouble you're seeing. I'd like to be on the same page here.

If that's not possible, a little video demonstrating the problem would help as well.

@rumit91

This comment has been minimized.

Copy link
Contributor

@rumit91 rumit91 commented Jun 24, 2015

@EddyVerbruggen, thanks for the quick reply! I created a repo that captures this issue: https://github.com/rumit91/PhoneGapKeyboardIssue. I didn't get my partial fix working the same way I have it our production repo (see readme for details), but this still illustrates the problem that we are experiencing. Any ideas?

@rumit91

This comment has been minimized.

Copy link
Contributor

@rumit91 rumit91 commented Jun 26, 2015

I was finally able to clean up my partial fix and get my production repo to work the way we intended it to (similar to the messages app on iOS) by adding the following to the ReroutingUIWebView.m:

- (void)layoutSubviews {
    self.wkWebView.frame = self.frame;
    self.wkWebView.scrollView.delegate = self;
}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    [self.scrollView.delegate scrollViewDidScroll:scrollView];
}

Two things are going on here:

  • The keyboard plugin changes the frame of the ReroutingUIWebView.m which in turn triggers layoutSubviews where I change the underlying wkWebView to be the right size.
  • When the keyboard comes up or the user taps a key, the wkWebView's scrollView gets offset by some calculated height. To disable this the cordova-plugin-keyboard adds a delegate to the ReroutingUIWebView's scrollView which resets the offset to 0. We need this to apply to the wkWebView's scrollView so I added a delegate that passes the command down to cordova-plugin-keyboard's delegate.

@EddyVerbruggen, do you think this is a valid solution? If you agree, I can get it working in my test repo and then submit a pull request.

@EddyVerbruggen

This comment has been minimized.

Copy link
Member

@EddyVerbruggen EddyVerbruggen commented Jun 28, 2015

@rumit91 Amazing work, I'd love to integrate the fix if we can add this to ReroutingUIWebView.m without changing behavior for folks not using cordova-plugin-keyboard. Which seems to be the case.

And how about pushing the adjusted cordova-plugin-keyboard to npm (with a new ID like cordova-plugin-keyboard-for-wkwebview) so folks can use that one?

@rumit91

This comment has been minimized.

Copy link
Contributor

@rumit91 rumit91 commented Jun 29, 2015

Yes, this pull request (#124) should not change the behavior for people not using cordova-plugin-keyboard. Even better: it does not require any changes to the actual cordova-plugin-keyboard code!

@EddyVerbruggen

This comment has been minimized.

Copy link
Member

@EddyVerbruggen EddyVerbruggen commented Jul 1, 2015

@rumit91 Thanks so much for the PR, it's now been merged into master. Perhaps a few peeps want to try it before I tag a new release. My own tests have been very promising.

@rumit91

This comment has been minimized.

Copy link
Contributor

@rumit91 rumit91 commented Jul 1, 2015

@EddyVerbruggen Thank you!

@hussfelt

This comment has been minimized.

Copy link

@hussfelt hussfelt commented Jul 5, 2015

Thank you all!

To clarify; No need to install any additional packages, the above PR should solve this issue? :)

@EddyVerbruggen

This comment has been minimized.

Copy link
Member

@EddyVerbruggen EddyVerbruggen commented Jul 5, 2015

@hussfelt You need toalso install cordova-plugin-keyboard because this issue is about using that plugin.

@northkode

This comment has been minimized.

Copy link

@northkode northkode commented Jul 7, 2015

Is this fix in master? I just installed this and the keyboard and the
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true); does not work.
neither does the disable scroll

@northkode

This comment has been minimized.

Copy link

@northkode northkode commented Jul 7, 2015

error setHackishlyHidesInputAccessoryView:]: unrecognized selector sent to instance 0x7fd139d53ee0
2015-07-07 09:22:14.414 lokel[16544:7245396] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[ReroutingUIWebView setHackishlyHidesInputAccessoryView:]: unrecognized selector sent to instance 0x7fd139d53ee0'
*** First throw call stack:
(
0 CoreFoundation 0x000000010d594c65 exceptionPreprocess + 165
1 libobjc.A.dylib 0x0000000110ea7bb7 objc_exception_throw + 45
2 CoreFoundation 0x000000010d59c0ad -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3 CoreFoundation 0x000000010d4f213c __forwarding
+ 988
4 CoreFoundation 0x000000010d4f1cd8 _CF_forwarding_prep_0 + 120
5 lokel 0x000000010d1ad78c -[IonicKeyboard setHideKeyboardAccessoryBar:] + 124
6 lokel 0x000000010d1adc50 -[IonicKeyboard hideKeyboardAccessoryBar:] + 368
7 lokel 0x000000010d1998ca -[CDVCommandQueue execute:] + 874
8 lokel 0x000000010d1ac5ff -[MyMainViewController userContentController:didReceiveScriptMessage:] + 303
9 WebKit 0x00000001104b74ce _ZN28ScriptMessageHandlerDelegate14didPostMessageERN6WebKit12WebPageProxyERNS0_13WebFrameProxyERN7WebCore21SerializedScriptValueE + 434
10 WebKit 0x0000000110537ea9 _ZN6WebKit29WebUserContentControllerProxy14didPostMessageEPN3IPC10ConnectionEyyyRKNS1_13DataReferenceE + 203
11 WebKit 0x000000011049b424 ZN3IPC13handleMessageIN8Messages29WebUserContentControllerProxy14DidPostMessageEN6WebKit29WebUserContentControllerProxyEMS5_FvPNS_10ConnectionEyyyRKNS_13DataReferenceEEEEvS7_RNS_14MessageDecoderEPT0_T1 + 134
12 WebKit 0x0000000110412f58 _ZN3IPC18MessageReceiverMap15dispatchMessageEPNS_10ConnectionERNS_14MessageDecoderE + 120
13 WebKit 0x0000000110551d9c _ZN6WebKit15WebProcessProxy17didReceiveMessageEPN3IPC10ConnectionERNS1_14MessageDecoderE + 24
14 WebKit 0x000000011039abaa _ZN3IPC10Connection15dispatchMessageENSt3__110unique_ptrINS_14MessageDecoderENS1_14default_deleteIS3_EEEE + 94
15 WebKit 0x000000011039d5c4 _ZN3IPC10Connection18dispatchOneMessageEv + 110
16 JavaScriptCore 0x0000000118247436 _ZN3WTF7RunLoop11performWorkEv + 454
17 JavaScriptCore 0x0000000118247cea _ZN3WTF7RunLoop11performWorkEPv + 26
18 CoreFoundation 0x000000010d4c8431 CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION + 17
19 CoreFoundation 0x000000010d4be2fd __CFRunLoopDoSources0 + 269
20 CoreFoundation 0x000000010d4bd934 __CFRunLoopRun + 868
21 CoreFoundation 0x000000010d4bd366 CFRunLoopRunSpecific + 470
22 GraphicsServices 0x00000001124afa3e GSEventRunModal + 161
23 UIKit 0x000000010d98d8c0 UIApplicationMain + 1282
24 lokel 0x000000010d19f7a1 main + 65
25 libdyld.dylib 0x00000001115dc145 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

@rumit91

This comment has been minimized.

Copy link
Contributor

@rumit91 rumit91 commented Jul 7, 2015

@northkode From your error it looks like you are running the Ionic Keyboard Plugin. This fix should address the issues with cordova-plugin-keyboard. Could you try it with the plugin found here: https://github.com/apache/cordova-plugins/tree/master/keyboard?

@northkode

This comment has been minimized.

Copy link

@northkode northkode commented Jul 7, 2015

ok ill give that a go. Thanks!

@northkode

This comment has been minimized.

Copy link

@northkode northkode commented Jul 8, 2015

I installed the repo mentioned but the functionality does not work.
The hide accessory is fixed.. but shrinkView and disableScroll are still not doing there jobs.

and no onShow events are fired.. the functions never run.

@rumit91

This comment has been minimized.

Copy link
Contributor

@rumit91 rumit91 commented Jul 8, 2015

Would you mind showing us your code or an example project that we can debug?

@northkode

This comment has been minimized.

Copy link

@northkode northkode commented Jul 9, 2015

i can't build a sample project at the moment..
and as far as the code goes.. I installed the cordova.plugins.keyboard that you mentioned above ^.
I installed the wkwebview and I call Keyboard.shrinkView(true) or false and it doesn't change the behaviour.. also the disableScrolling doesn't work either.. they do absolutely nothing.

I will try and put some nslogs in the keyboard methods and see if its even trying to apply the changes.

using the exact same plugin without your wkwebview it works great.

@rumit91

This comment has been minimized.

Copy link
Contributor

@rumit91 rumit91 commented Jul 9, 2015

Ok I'll try to find some time in the next few days to test it out more. It seems to work great in my production code, so I'm not sure why it's not working as expected :(

@rumit91

This comment has been minimized.

Copy link
Contributor

@rumit91 rumit91 commented Jul 14, 2015

@northkode could you double check that you have the right version of the WKWebView plugin? Does your ReroutingUIWebView.m file have this code?

Here's my example project that illustrates the keyboard plugin working with the wkwebview using the fix above. I'm currently trying to figure out why the scrolling behavior does not work as expected when the keyboard is active, but that's a different problem and shouldn't affect the Keyboard.shrinkView(true) behavior.

@woniesong92

This comment has been minimized.

Copy link

@woniesong92 woniesong92 commented Aug 8, 2015

I really would like to us WKWebView if the keyboard problem was solved. Is the problem with hiding accessory bar and scrolling fixed with the above PR?

@EddyVerbruggen

This comment has been minimized.

Copy link
Member

@EddyVerbruggen EddyVerbruggen commented Aug 8, 2015

The scroll should be fine (in master, not in a released version yet). The accessory bar can't be hidden.

@woniesong92

This comment has been minimized.

Copy link

@woniesong92 woniesong92 commented Aug 8, 2015

@EddyVerbruggen That's great! I think having the accessory bar will be an acceptable compromise for the performance boost you get. Do you also happen to know the status bar problem? I am using Meteor-ionic, and this issue describes the problem I encounter with the current version of WKWebview. Could you tell me if these problems have been fixed?

@woniesong92

This comment has been minimized.

Copy link

@woniesong92 woniesong92 commented Aug 14, 2015

@rumit91 your code saved a ton of work. For anyone who will struggle in future, this is a way to get disableScroll() working.

@clauderic

This comment has been minimized.

Copy link

@clauderic clauderic commented Aug 19, 2015

This fix works great. Thanks a lot. Not sure if this is related, but I've noticed there's a black background when the viewport resizes. Any way to change that? Perhaps to a white background at least so it's less visually offensive?
keyboard-background-glitch

Also, although kind of obvious in hindsight, might help some people out there: you have to make sure to specifically run cordova plugin add https://github.com/Telerik-Verified-Plugins/WKWebView to get this fix... took me a little while to figure out it hadn't been released yet.

@rumit91

This comment has been minimized.

Copy link
Contributor

@rumit91 rumit91 commented Aug 19, 2015

Thanks @woniesong92! @berickson1 actually found an even better fix. It's already in master so you should be able to get it using cordova plugin add https://github.com/Telerik-Verified-Plugins/WKWebView as @clauderic mentioned.

My team and I were still able to hide the accessory bar using the cordova.plugin.Keyboard and the Keyboard.hideFormAccessoryBar(true) command, so give that another try, @woniesong92.

@clauderic I had submitted this pull request that should make the WKWebView respect the background color property set in config.xml. However, looking back at our app it looks like that didn't completely fix the problem or there was some regression. The black background still appears when the keyboard is brought up but it at least goes to white when the keyboard is dismissed. Try setting that background color property and see what happens.

@EddyVerbruggen

This comment has been minimized.

Copy link
Member

@EddyVerbruggen EddyVerbruggen commented Aug 23, 2015

Hi @rumit91 that PR did work, but the recent keyboard scroll fix has broken this. Thanks @clauderic for the gif. With the latest release (0.5.0) this should be fixed. Default is white and it can be overridden as before.

@mluria

This comment has been minimized.

Copy link

@mluria mluria commented Feb 28, 2016

I'd like to use cordova-plugin-wkwebview-engine along with cordova.plugins.Keyboard. Has this been incorporated there?

https://issues.apache.org/jira/browse/CB-10724?filter=-2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
You can’t perform that action at this time.