12

iOS7 では、 UIKeyboardAppearanceが導入されました。に適用するUITextViewとうまく機能しますが、Apple が述べているように、 はプロトコルに準拠してUIWebViewいません。UITextInputTraits

UIWebView クラスは UITextInputTraits プロトコルを直接サポートしていませんが、テキスト入力要素のいくつかのキーボード属性を構成できます。たとえば、次の例に示すように、input 要素の定義に autocorrect 属性と auto-capitalization 属性を含めて、キーボードの動作を指定できます。

キーボードの外観を設定するための魔法の HTML 属性を理解した人はいますか? それとも一つもありませんか?回避策はありますか?(非公開 API は使用しないでください)

4

1 に答える 1

11

非常に簡単な解決策は、- (UIKeyboardAppearance) keyboardAppearanceカテゴリ拡張を介して にメソッドを追加することUIViewです。このメソッドでは、単純に を返すことができますUIKeyboardAppearanceDark。これが機能するのは、ユーザーが HTML フォームの入力フィールドをタップしたときに最初のレスポンダーとなる内部UIWebViewビュー ( ) にメソッドが魔法のように追加されるためです。UIWebBrowserViewこのアプローチの主な問題は、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
于 2014-04-30T21:39:25.327 に答える