自定义webview键盘问题

时间:2015-02-23 00:01:56

标签: ios webview keyboard appearance

因此,通过此线程UIKeyboardAppearance in UIWebViewTomSwift's调整代码,我得到了大约99%的工作。

在iOS 7模拟器中,一切似乎都运行得很好。然而,在iOS 8中,当键盘首次出现时,< >完成栏是白色的。当我点击或选择另一个输入时,它会变为我指定的颜色。

我的问题是,如何预防和/或更改白色部分?

White Bar Dark Bar

另一个线程中的所有代码都是相同的,除了我在keyboardWillAppear中调用的颜色。

UIWindow *keyboardWindow = nil;
for (UIWindow *testWindow in [[UIApplication sharedApplication] windows]) {
    if (![[testWindow class] isEqual : [UIWindow class]]) {
        keyboardWindow = testWindow;
        break;
    }
}

// Locate UIWebFormView.
for (UIView *possibleFormView in [keyboardWindow subviews]) {
    if ([[possibleFormView description] hasPrefix : @"<UIInputSetContainerView"]) {

        for (UIView* peripheralView in possibleFormView.subviews) {
            peripheralView.backgroundColor = [UIColor colorWithRed:0.271 green:0.271 blue:0.271 alpha:0.75];

            for (UIView* peripheralView_sub in peripheralView.subviews) {
                peripheralView_sub.backgroundColor = [UIColor colorWithRed:0.271 green:0.271 blue:0.271 alpha:0.75];

            }
        }
    }
}

非常感谢任何帮助。

6 个答案:

答案 0 :(得分:4)

因此,对于iOS 9+,我发现它打破了上述方法。但是通过一些修补和浏览一些观点,我想出了我已经在下面回答的内容。

现在我决定放弃自定义颜色,我只是挖黑色键盘,适合我的应用。无论如何,这对我有用。在9.1 sim到7上测试。还在我的6+运行9.0.2。

//Keyboard setting
@interface UIWebBrowserView : UIView
@end
@interface UIWebBrowserView (UIWebBrowserView_Additions)
@end
@implementation UIWebBrowserView (UIWebBrowserView_Additions)
- (id)inputAccessoryView {
    return nil;
}

- (UIKeyboardAppearance) keyboardAppearance{

    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    BOOL switchOn = [userDefaults boolForKey:@"darkKeyboard"];

    if (switchOn) {
        return UIKeyboardAppearanceDark;
    }
    else {
        return UIKeyboardAppearanceDefault;
    }
}
@end

@interface UITextInputTraits : UIWebBrowserView
@end
@interface UITextInputTraits (UIWebBrowserView)
@end
@implementation UITextInputTraits (UIWebBrowserView)
- (UIKeyboardAppearance) keyboardAppearance{

    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    BOOL switchOn = [userDefaults boolForKey:@"darkKeyboard"];

    if (switchOn) {
        return UIKeyboardAppearanceDark;
    }
    else {
        return UIKeyboardAppearanceDefault;
    }
}
@end

我真的希望有人觉得这些答案很有用:D

更新信息: 对完成的酒吧感到好奇,这就是这一切的开始。我重新启用它只是为了看到,并发现它改变为黑色。很好的奖励,虽然我已经放弃了它以隐藏键盘滚动。

2015年12月19日更新 所以我决定从UIWebView转换到WKWebView,但发现两者之间显然有所不同。我设法让它再次运作。定期UIKeyboardAppearanceDark调用使键盘比我喜欢的更透明。所以我根据自己的喜好修改了它。再说一次,可能不是标准的做事方式,但我不在乎,反正它也不会去苹果。

一切仍然存在于AppDelegate中。

//Removing the input bar above the keyboard.
@interface InputHider : NSObject @end
@implementation InputHider
-(id)inputAccessoryView{
    return nil;
}
@end

@interface UIWebBrowserView : NSObject
@end
@interface NSObject (UIWebBrowserView_Additions)
@end
@implementation NSObject (UIWebBrowserView_Additions)
- (UIKeyboardAppearance) keyboardAppearance{
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    BOOL switchOn = [userDefaults boolForKey:@"darkKeyboard"];

    if (switchOn) {
        UIWindow *keyboardWindow = nil;
        for (UIWindow *testWindow in [[UIApplication sharedApplication] windows]) {
            if (![[testWindow class] isEqual : [UIWindow class]]) {
                keyboardWindow = testWindow;
                break;
            }
        }

        // Locate UIWebFormView.
        for (UIView *possibleFormView in [keyboardWindow subviews]) {

            if ([possibleFormView isKindOfClass:NSClassFromString(@"UIInputSetContainerView")] ||
                [possibleFormView isKindOfClass:NSClassFromString(@"UIInputSetHostView")]) {
                for (UIView* peripheralView in possibleFormView.subviews) {
                    peripheralView.backgroundColor = [UIColor colorWithRed:0.271 green:0.271 blue:0.271 alpha:1.0];

                    //Keyboard background
                    for (UIView* peripheralView_sub in peripheralView.subviews) {
                        peripheralView_sub.backgroundColor = [UIColor colorWithRed:0.271 green:0.271 blue:0.271 alpha:1.0];

                        //Accessory bar color
                        if ([possibleFormView isKindOfClass:NSClassFromString(@"WKContentView")]) {
                            for (UIView* UIInputViewContent_sub in peripheralView_sub.subviews) {
                                [[UIInputViewContent_sub layer] setOpacity : 1.0];
                                UIInputViewContent_sub.backgroundColor = [UIColor colorWithRed:0.271 green:0.271 blue:0.271 alpha:1.0];

                            }
                        }
                    }
                }
            }
        }
        return UIKeyboardAppearanceDark;
    }
    else {
        UIWindow *keyboardWindow = nil;
        for (UIWindow *testWindow in [[UIApplication sharedApplication] windows]) {
            if (![[testWindow class] isEqual : [UIWindow class]]) {
                keyboardWindow = testWindow;
                break;
            }
        }

        // Locate UIWebFormView.
        for (UIView *possibleFormView in [keyboardWindow subviews]) {

            if ([possibleFormView isKindOfClass:NSClassFromString(@"UIInputSetContainerView")] || [possibleFormView isKindOfClass:NSClassFromString(@"UIKeyboard")]) {
                for (UIView* peripheralView in possibleFormView.subviews) {
                    peripheralView.backgroundColor = [UIColor clearColor];

                    //Keyboard background
                    for (UIView* peripheralView_sub in peripheralView.subviews) {
                        peripheralView_sub.backgroundColor = [UIColor clearColor];

                        //Accessory bar color
                        if ([possibleFormView isKindOfClass:NSClassFromString(@"UIWebFormAccessory")]) {
                            for (UIView* UIInputViewContent_sub in peripheralView_sub.subviews) {
                                [[UIInputViewContent_sub layer] setOpacity : 1.0];
                                UIInputViewContent_sub.backgroundColor = [UIColor clearColor];

                            }
                        }
                    }
                }
            }
        }
        return UIKeyboardAppearanceDefault;
    }
}
@end

@interface UITextInputTraits : UIWebBrowserView
@end
@interface UITextInputTraits (UIWebBrowserView)
@end
@implementation UITextInputTraits (UIWebBrowserView)
- (UIKeyboardAppearance) keyboardAppearance{
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    BOOL switchOn = [userDefaults boolForKey:@"darkKeyboard"];

    if (switchOn) {
        return UIKeyboardAppearanceDark;
    }
    else {
        return UIKeyboardAppearanceDefault;
    }
}
@end

//Disables endDisablingInterfaceAutorotationAnimated error for keyboard
@interface UIWindow (UIWebBrowserView)
- (void)beginDisablingInterfaceAutorotation;
- (void)endDisablingInterfaceAutorotation;
@end

@implementation UIWindow (UIWebBrowserView)
- (void)beginDisablingInterfaceAutorotation {}
- (void)endDisablingInterfaceAutorotation{}
@end

我还没有像以前那样设法隐藏inputAccessoryBar,但多亏了几个线程我才开始工作。在我的视图控制器中,我打电话:

-(void)removeInputAccessoryView {
    UIView* subview;

    for (UIView* view in webView.scrollView.subviews) {
        if([[view.class description] hasPrefix:@"WKContent"])
            subview = view;
    }

    if(subview == nil) return;

    NSString* name = [NSString stringWithFormat:@"%@SwizzleHelper", subview.class.superclass];
    Class newClass = NSClassFromString(name);

    if(newClass == nil)
    {
        newClass = objc_allocateClassPair(subview.class, [name cStringUsingEncoding:NSASCIIStringEncoding], 0);
        if(!newClass) return;

        Method method = class_getInstanceMethod([AppDelegate class], @selector(inputAccessoryView));
        class_addMethod(newClass, @selector(inputAccessoryView), method_getImplementation(method), method_getTypeEncoding(method));

        objc_registerClassPair(newClass);
    }

    object_setClass(subview, newClass);
}

在viewDidLoad中我调用:

[self removeInputAccessoryView];

我计划修补一些,但就目前来说,这符合我的需要。

答案 1 :(得分:3)

WKWebView键盘

这是WKWebView的一个解决方案,它使用调配,并且相当容易合并并适用于iOS 9,10&amp; 11.只需创建一个名为 WKKeyboard 的新类,并添加以下代码:

WKKeyboard.h

#import <Foundation/Foundation.h>
#import <WebKit/WebKit.h>

@interface WKKeyboard : NSObject

+ (void)setStyle:(UIKeyboardAppearance)style on:(WKWebView *)webView;

@end

WKKeyboard.m

#import "WKKeyboard.h"
#import <objc/runtime.h>

@implementation WKKeyboard

// Allows the changing of keyboard styles
static UIKeyboardAppearance keyboardStyle;

// Leave this as an instance method
- (UIKeyboardAppearance)keyboardAppearance {
    return keyboardStyle;
}

// This can be a class method
+ (void)setStyle:(UIKeyboardAppearance)style on:(WKWebView *)webView {
    for (UIView *view in [[webView scrollView] subviews]) {
        if([[view.class description] containsString:@"WKContent"]) {
            UIView *content = view;
            NSString *className = [NSString stringWithFormat:@"%@_%@",[[content class] superclass],[self class]];
            Class newClass = NSClassFromString(className);
            if (!newClass) {
              newClass = objc_allocateClassPair([content class], [className cStringUsingEncoding:NSASCIIStringEncoding], 0);
              Method method = class_getInstanceMethod([WKKeyboard class], @selector(keyboardAppearance));
              class_addMethod(newClass, @selector(keyboardAppearance), method_getImplementation(method), method_getTypeEncoding(method));
              objc_registerClassPair(newClass);
            }
            object_setClass(content, newClass);
            keyboardStyle = style;
            return;
        }
    }
}

@end

用法

// The WKWebView you want to change the keyboard on
WKWebView *webView = [WKWebView alloc] init];

// Then just call the class method with the style and webview
[WKKeyboard setStyle:UIKeyboardAppearanceDark on:webView];

希望这对某人有帮助,这样你可以选择性地改变单个WKWebView上的外观,而不是所有这些!

答案 2 :(得分:0)

虽然让这个工作很好,但我决定采取完全放弃的方法,而是使用水龙头来解雇键盘。

我的印象是隐藏它也会隐藏自动更正条。事实并非如此。

以下是我正在使用的完整代码。

键盘的最终颜色代码,在我的应用设置中由切换开关调用。

NSUserDefaults *darkDefaults = [NSUserDefaults standardUserDefaults];
BOOL darkOn = [darkDefaults boolForKey:@"darkKeyboard"];

if (darkOn) {
    UIWindow *keyboardWindow = nil;
    for (UIWindow *testWindow in [[UIApplication sharedApplication] windows]) {
        if (![[testWindow class] isEqual : [UIWindow class]]) {
            keyboardWindow = testWindow;
            break;
        }
    }

    // Locate UIWebFormView.
    for (UIView *possibleFormView in [keyboardWindow subviews]) {

        if ([possibleFormView isKindOfClass:NSClassFromString(@"UIInputSetContainerView")]) {
            for (UIView* peripheralView in possibleFormView.subviews) {

                //Keyboard background
                for (UIView* peripheralView_sub in peripheralView.subviews) {
                    peripheralView_sub.backgroundColor = [UIColor colorWithRed:0.271 green:0.271 blue:0.271 alpha:0.75];
                }
            }
        }
    }
}
else{
    UIWindow *keyboardWindow = nil;
    for (UIWindow *testWindow in [[UIApplication sharedApplication] windows]) {
        if (![[testWindow class] isEqual : [UIWindow class]]) {
            keyboardWindow = testWindow;
            break;
        }
    }

    // Locate UIWebFormView.
    for (UIView *possibleFormView in [keyboardWindow subviews]) {

        if ([possibleFormView isKindOfClass:NSClassFromString(@"UIInputSetContainerView")]) {
            for (UIView* peripheralView in possibleFormView.subviews) {

                //Keyboard background
                for (UIView* peripheralView_sub in peripheralView.subviews) {
                    peripheralView_sub.backgroundColor = [UIColor clearColor];
                }
            }
        }
    }
}

隐藏键盘。在我的视图控制器的顶部调用(可能不是苹果安全,但我没有必要发布,所以它适用于我):

@interface UIWebBrowserView : UIView
@end

@implementation UIWebBrowserView (CustomToolbar)
- (id)inputAccessoryView {
    return nil;
}
@end

现在从我的测试中,我可以通过在inputAccessoryView部分中绘制一个新的视图或工具栏来对其进行着色,但是用它来解除混乱,需要进行一些调整,但这不是正常的我打算去的标准酒吧。哦,好吧。

如果您想要从表格视图中实现切换,请按照以下方式进行操作。

- (id)init{
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(reloadTableView:)
                                                 name:NSUserDefaultsDidChangeNotification object:nil];

    return [self initWithStyle:UITableViewStyleGrouped];
}

的cellForRowAtIndexPath:

                [cell.textLabel setText:@"Dark Keyboard"];
                cell.textLabel.textAlignment = NSTextAlignmentLeft;
                cell.selectionStyle = UITableViewCellSelectionStyleNone;
                darkKeyboard = [[UISwitch alloc] initWithFrame: CGRectMake(7, 0, 0, 0)];
                cell.accessoryView = [[UIView alloc] initWithFrame:darkKeyboard.frame];
                [cell.accessoryView addSubview:darkKeyboard];
                [self.darkKeyboard addTarget:self action:@selector(updateSwitchAtIndexPath:) forControlEvents:UIControlEventValueChanged];

                //On Color
                darkKeyboard.onTintColor = [UIColor colorWithRed:0.204 green:0.667 blue:0.863 alpha:0.85];
                //Off Color
                darkKeyboard.backgroundColor = [UIColor colorWithRed:0.678 green:0.161 blue:0.188 alpha:0.75];
                darkKeyboard.TintColor = [UIColor clearColor];
                darkKeyboard.layer.cornerRadius = 16.0;
                //Risize
                darkKeyboard.transform = CGAffineTransformMakeScale(1.1, 1.1);
                //User defaults
                darkKeyboard.on = [[NSUserDefaults standardUserDefaults] boolForKey:@"darkKeyboard"];

                UIView *keyboard = [[UIView alloc] initWithFrame:cell.frame];
                keyboard.backgroundColor = [UIColor colorWithRed:0.176 green:0.176 blue:0.176 alpha:1];
                cell.backgroundView = keyboard;

didSelectRowAtIndexPath方法: 刚刚添加了一个NSLog,没有什么需要去的。

- (void)updateSwitchAtIndexPath:(id)sender {

    if (darkKeyboard){
        NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
        [userDefaults setBool:self.darkKeyboard.on forKey:@"darkKeyboard"];
        [userDefaults synchronize];

        if ([darkKeyboard isOn]) {
            [darkKeyboard setOn:YES animated:YES];
            [self.tableView reloadData];
            [[UIApplication sharedApplication] reloadInputViews];

        } else {
            [darkKeyboard setOn:NO animated:YES];
            [self.tableView reloadData];
            [[UIApplication sharedApplication] reloadInputViews];
        }
    }

}

希望这有助于某人。

答案 3 :(得分:0)

像下面那样扩展UIWebBrowserView,将使您被应用商店禁止。

http:///

因此,您需要在运行时扩展Web视图。

以下代码以与iOS12兼容且不会被Apple拒绝的方式实现此目的。 对于此示例,我使用全局@interface UIWebBrowserView : UIView @end @implementation UIWebBrowserView (KeyboardSwitch) - (UIKeyboardAppearance) keyboardAppearance{ return UIKeyboardAppearanceDark; } @end 来确定所需的键盘样式。

_s_isDark

答案 4 :(得分:0)

@Asleepace's答案的快速版本。而且它对我来说很有效。方法混乱是一种前往此处的方法。

class WKKeybaord: NSObject {
static var keyboardStyle: UIKeyboardAppearance = .default

@objc func keyboardAppearance() -> UIKeyboardAppearance {
    return WKKeybaord.keyboardStyle
}

class func setStyle(with style: UIKeyboardAppearance, on webView: WKWebView) {
    for view in webView.scrollView.subviews {
        if view.self.description.contains("WKContent") {
            let content = view
            var className: String? = nil
            if let superclass = content.self.superclass {
                className = "\(superclass)_\(type(of: self))"
            }
            var newClass: AnyClass? = NSClassFromString(className ?? "")
            if newClass == nil {
                newClass = objc_allocateClassPair(object_getClass(content), className ?? "", 0)
                if let method = class_getInstanceMethod(WKKeybaord.self, #selector(self.keyboardAppearance)) {
                    class_addMethod(newClass, #selector(self.keyboardAppearance), method_getImplementation(method), method_getTypeEncoding(method))
                    objc_registerClassPair(newClass!)
                }
            }
            object_setClass(content, newClass!)
            keyboardStyle = style
            return
        }
    }
}
}

答案 5 :(得分:-1)

替代答案。

因此,不用尝试定义另一种颜色,只需使用上面提到的开关获得浅色或深色外观即可。我把这个添加到我的AppDelegate,(有些人不喜欢在这里添加内容,但在我的应用程序中有这么多的视图,这是必须的)。

@interface AppDelegate ()

上方添加此项
@interface UIWebBrowserView : UIView
@end

@implementation UIWebBrowserView (KeyboardSwitch)

- (UIKeyboardAppearance) keyboardAppearance{

    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    BOOL switchOn = [userDefaults boolForKey:@"darkKeyboard"];

    if (switchOn) {
        return UIKeyboardAppearanceDark;
    }
    else {
        return UIKeyboardAppearanceDefault;
    }
}
@end

完美无缺。可能不会被苹果公司接受,但我对此毫无兴趣。

现在,对于那些不想创建切换并且只想要黑暗键盘的人来说。

@interface UIWebBrowserView : UIView
@end

@implementation UIWebBrowserView (KeyboardSwitch)

- (UIKeyboardAppearance) keyboardAppearance{

    return UIKeyboardAppearanceDark;
}
@end

更新: 使用自定义颜色:在模拟器中从iOS 7-8.2进行测试。

- (UIKeyboardAppearance) keyboardAppearance{

    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    BOOL switchOn = [userDefaults boolForKey:@"darkKeyboard"];

    if (switchOn) {
        UIWindow *keyboardWindow = nil;
        for (UIWindow *testWindow in [[UIApplication sharedApplication] windows]) {
            if (![[testWindow class] isEqual : [UIWindow class]]) {
                keyboardWindow = testWindow;
                break;
            }
        }

        for (UIView *possibleFormView in [keyboardWindow subviews]) {
            if ([possibleFormView isKindOfClass:NSClassFromString(@"UIInputSetContainerView")] || [possibleFormView isKindOfClass:NSClassFromString(@"UIPeripheralHostView")]) {
                for (UIView* peripheralView in possibleFormView.subviews) {

                    //Keyboard background
                    for (UIView* peripheralView_sub in peripheralView.subviews) {
                        //Setting custom color
                        peripheralView_sub.backgroundColor = [UIColor colorWithRed:0.271 green:0.271 blue:0.271 alpha:0.50];
                    }
                }
            }
        }
        return UIKeyboardAppearanceDark;
    }
    else {
        UIWindow *keyboardWindow = nil;
        for (UIWindow *testWindow in [[UIApplication sharedApplication] windows]) {
            if (![[testWindow class] isEqual : [UIWindow class]]) {
                keyboardWindow = testWindow;
                break;
            }
        }

        for (UIView *possibleFormView in [keyboardWindow subviews]) {
            if ([possibleFormView isKindOfClass:NSClassFromString(@"UIInputSetContainerView")] || [possibleFormView isKindOfClass:NSClassFromString(@"UIPeripheralHostView")]) {
                for (UIView* peripheralView in possibleFormView.subviews) {

                    //Keyboard background
                    for (UIView* peripheralView_sub in peripheralView.subviews) {
                        //Clear color so it doesn't show when switching with toggle
                        peripheralView_sub.backgroundColor = [UIColor clearColor];
                    }
                }
            }
        }
        return UIKeyboardAppearanceDefault;
    }
}
@end

希望这有助于未来的webview开发人员。