How the default keyboard comes up when user taps in UIWebView?
Well, if you can't beat them, join them.
As far as I know, and I tried. You can't change the inputView or the inputAccessoryView without using a private class (UIWebBrowserView).
But you can detect when the keyboard appears, with the notification UIKeyboardWillShowNotification. So, how about do a man in the middle?
I mean, use a UITextField like a buffer.
Let me explain a little more.
When the keyboard appears, you can check if the first responder is the UIWebView, if it is, you can become a textview as the first responder.
What do you win with that? The text typed with the keyboard go to the text view.
That is useless, you would say. Of course, but how about change the input view of the textview? How? With this https://github.com/kulpreetchilana/Custom-iOS-Keyboards
You have a custom keyboard when the user is writing in the web view!!!
How can you put the textview's text in the webview?
Easy, Put the textview's text in the input of the inner html with textViewDidChange and javascript.
- (void)textViewDidChange:(UITextView *)textView{
NSString* script = [NSString stringWithFormat:@"document.activeElement.value = '%@';", textView.text];
[self stringByEvaluatingJavaScriptFromString:script];
}
I put in bold the main phrases of the idea.
But, maybe my explanation is difficult to understand. Or my English is bad, so I uploade a sample project with the idea.
How to set a custom keyboard for UIWebView
I believe there is no way to do this as of now. Hence, my current approach is to use a custom view below the keyboard and hide the keyboard and show the keyboard as required.
fill UIWebVIew TextInput with custom keyboard
Check dcorbatta's answer in this article Custom Keyboard in UIWebView
He suggest to use a UITextField as a "media" when you detect keyboard coming up inside a UIWebView. Thus, you can use whatever Keyboard type you want on the UITextField. After users taps something, copy the text in UITextField the media via JavaScript ActiveDocument.
How to change keyboard button Return to Search for input in a UIWebView?
I found a simple solution. Just wrap the input with form tag so the HTML looks like this.
<html>
<body>
<p>
<form>
<input name='search' type='search' placeholder="Input type is search" />
</form>
</body>
</html>
And now the keyboard looks like
Keyboard gets dismissed when tapping into UIWebViews
As it turns out, after scrounging the internet for a week for this and related problems, I ended up finding a duplicate question! I'm reposting the relevant code from this post by diegoreymendez.
UIWebView+GUIFixes.h
#import <UIKit/UIKit.h>
@interface UIWebView (GUIFixes)
/**
* @brief Wether the UIWebView will use the fixes provided by this category or not.
*/
@property (nonatomic, assign, readwrite) BOOL usesGUIFixes;
@end
UIWebView+GUIFixes.m
#import "UIWebView+GUIFixes.h"
#import <objc/runtime.h>
@implementation UIWebView (GUIFixes)
static const char* const fixedClassName = "UIWebBrowserViewMinusAccessoryView";
static Class fixClass = Nil;
- (UIView *)browserView
{
UIScrollView *scrollView = self.scrollView;
UIView *browserView = nil;
for (UIView *subview in scrollView.subviews) {
if ([NSStringFromClass([subview class]) hasPrefix:@"UIWebBrowserView"]) {
browserView = subview;
break;
}
}
return browserView;
}
- (BOOL)delayedBecomeFirstResponder
{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[super becomeFirstResponder];
});
return YES;
}
- (void)ensureFixedSubclassExistsOfBrowserViewClass:(Class)browserViewClass
{
if (!fixClass) {
Class newClass = objc_allocateClassPair(browserViewClass, fixedClassName, 0);
objc_registerClassPair(newClass);
IMP delayedFirstResponderImp = [self methodForSelector:@selector(delayedBecomeFirstResponder)];
Method becomeFirstResponderMethod = class_getInstanceMethod(browserViewClass, @selector(becomeFirstResponder));
method_setImplementation(becomeFirstResponderMethod, delayedFirstResponderImp);
fixClass = newClass;
}
}
- (BOOL)usesGUIFixes
{
UIView *browserView = [self browserView];
return [browserView class] == fixClass;
}
- (void)setUsesGUIFixes:(BOOL)value
{
UIView *browserView = [self browserView];
if (browserView == nil) {
return;
}
[self ensureFixedSubclassExistsOfBrowserViewClass:[browserView class]];
if (value) {
object_setClass(browserView, fixClass);
}
else {
Class normalClass = objc_getClass("UIWebBrowserView");
object_setClass(browserView, normalClass);
}
[browserView reloadInputViews];
}
@end
It feels dirty and fragile having to deal with the objc runtime like this, but as far as I've found, its the only way that actually works.
Related Topics
This Action Could Not Be Completed. Try Again (-22421)
Difference Between Dispatch_Async and Dispatch_Sync on Serial Queue
Xcode 6 - Launch Simulator from Command Line
Calayer with Transparent Hole in It
Center Content of Uiscrollview When Smaller
Get the Right Color in iOS7 Translucent Navigation Bar
Formatting a Uitextfield for Credit Card Input Like (Xxxx Xxxx Xxxx Xxxx)
Which iOS App Version/Build Number(S) Must Be Incremented Upon App Store Release
Uiview Hide/Show with Animation
How to Center Align the Cells of a Uicollectionview
My App Was Just Rejected for Using the Ad Support Framework. Which Library Is Responsible
How to Mask a Square Image into an Image with Round Corners in iOS
Why Maskstobounds = Yes Prevents Calayer Shadow
Uinavigationcontroller "Back Button" Custom Text
How to Specify Size for iPhone 6/7 Customised Edge-To-Edge Image
iOS Static VS Dynamic Frameworks Clarifications