UIWebView中的UIKeyboardAppearance

mar*_*lar 12 objective-c uiwebview ios7

在iOS7中,我们看到了UIKeyboardAppearance的推出.应用时效果很好UITextView,但是,正如Apple声明的那样,UIWebView它不符合UITextInputTraits协议.

虽然UIWebView类不直接支持UITextInputTraits协议,但您可以为文本输入元素配置一些键盘属性.例如,您可以在input元素的定义中包含自动更正和自动大写属性,以指定键盘的行为,如以下示例所示.

有没有人想出为键盘外观设置的神奇HTML属性呢?或者没有一个?任何解决方法?(请不要私人API)

Tom*_*ift 11

一个非常简单的解决方案是- (UIKeyboardAppearance) keyboardAppearance通过类别扩展添加方法UIView.在这种方法中你可以简单地返回UIKeyboardAppearanceDark.这是有效的,因为该方法可以神奇地添加到内部UIWebView视图(UIWebBrowserView),当用户点击HTML表单输入字段时,该视图成为第一个响应者.这种方法的主要问题是它会影响所有UIView派生的视图,这可能是不可取的.

我们可以构建一个更有针对性的解决方案,它拦截负责键盘的第一个响应者,keyboardAppearance并在不存在的情况下为其添加方法.如果UIWebBrowserView将来的更改内部实现包含keyboardAppearance选择器,这将会优雅地降级.

#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
Run Code Online (Sandbox Code Playgroud)