objective-c - UIWebView 中的 UIKeyboardAppearance

标签 objective-c uiwebview ios7

在 iOS7 中,我们看到了 UIKeyboardAppearance 的引入.应用于 UITextView 时效果很好,但是,作为 Apple states , UIWebView 不符合 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.

有没有人想出神奇的 HTML 属性来设置键盘外观?还是没有?任何解决方法? (请不要使用私有(private) API)

最佳答案

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

我们可以构建一个更有针对性的解决方案,它拦截负责键盘的第一响应者,如果不存在,则向其添加 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

关于objective-c - UIWebView 中的 UIKeyboardAppearance,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19961103/

相关文章:

ios - 在应用程序和应用程序内的 webview 中共享 session - IOS Swift

iphone - 有时不调用 UIWebView 的 shouldStartLoadWithRequest

ios - 如何在 UIWebView 之上覆盖 UIButton(关闭)按钮?

iOS 7 : different navigation items for tab bar controller

iOS7 - 设置 UITabBarController 的 selectedIndex 会破坏屏幕右侧边缘的触摸事件?

ios - 需要 Storyboard元素处于正确的位置并且在不同的 iPhone 型号中具有正确的大小

objective-c - 添加非 NSObjects 到 NSMutableArray

objective-c - 可以在 Objective-c 中访问的协议(protocol)的扩展上定义 Swift 方法吗

ios - NSDateComponents(通过 MTDates)返回一个奇怪的小时数(mt_hourOfDay)

ios - SKScene 和 SKView 的暂停属性之间的区别