With iOS7, we saw the introduction of UIKeyboardAppearance. Works great when applied to UITextView
, but, as Apple states, the UIWebView
does not conform to the UITextInputTraits
protocol.
Although the UIWebView class does not support the UITextInputTraits protocol directly, you can configure some keyboard attributes for text input elements. For example, you can include autocorrect and auto-capitalization attributes in the definition of an input element to specify the keyboard’s behaviors, as shown in the following example.
Has anyone figured out the magical HTML attribute to set for keyboard appearance yet? Or is there not one? Any workaround? (No private APIs, please)
A very easy solution would be to add a - (UIKeyboardAppearance) keyboardAppearance
method via category extension to UIView
. In this method you could simply return UIKeyboardAppearanceDark
. This works because the method would magically be added to the internal UIWebView
view (UIWebBrowserView
) which becomes the first responder when the user taps into a HTML form input field. The main problem with this approach is that it will affect all UIView-derived views, which may not be desirable.
We can construct a more targeted solution which intercepts the first responder that is responsible for the keyboard and adds a keyboardAppearance
method to it if one doesn't exist. This will degrade gracefully if the internal implementation of UIWebBrowserView
changes in the future to include a keyboardAppearance
selector.
#import <objc/runtime.h>
@protocol TSPingPong <NSObject>
- (void) ts_pong: (id) sender;
@end
@interface NSObject (TSPingPong)
@end
@implementation NSObject (TSPingPong)
- (void) ts_ping: (id) sender
{
if ( [sender respondsToSelector: @selector(ts_pong:)] )
{
[sender performSelector: @selector( ts_pong: ) withObject: self ];
}
}
@end
@implementation TSViewController
{
IBOutlet UIWebView* _webView;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver: self
selector: @selector(keyboardWillAppear:)
name: UIKeyboardWillShowNotification
object: nil];
NSString* html = @"<br><br><br><form action=''> " \
"First name: <input type='text'><br> " \
"Last name: <input type='text'><br>" \
"<input type='submit' value='Submit'> " \
"</form>";
[_webView loadHTMLString: html
baseURL: nil];
}
- (void) keyboardWillAppear: (NSNotification*) n
{
// the keyboard is about to appear!
// play pingpong with the first responder so we can ensure it has a keyboardAppearance method:
[[UIApplication sharedApplication] sendAction: @selector( ts_ping:) // added via category extension
to: nil // to: the first responder
from: self // "sender"
forEvent: nil];
}
- (void) ts_pong: (id) sender
{
// sender is the first responder. Happens to be undocumented "UIWebBrowserView" in this case.
// if it doesn't have it's own keyboardAppearance method then let's add one:
if ( ![sender respondsToSelector: @selector(keyboardAppearance)] )
{
Method m = class_getInstanceMethod( [self class], @selector( keyboardAppearanceTemplateMethod ) );
IMP imp = method_getImplementation( m );
const char* typeEncoding = method_getTypeEncoding( m );
class_addMethod( [sender class], @selector(keyboardAppearance), imp, typeEncoding );
}
}
- (UIKeyboardAppearance) keyboardAppearanceTemplateMethod
{
return UIKeyboardAppearanceDark;
}
@end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With