【问题标题】:Keyboard gets dismissed when tapping into UIWebViews点击 UIWebViews 时键盘被关闭
【发布时间】:2015-07-09 09:19:19
【问题描述】:

我有一些用于富文本编辑的 UIWebView。他们有一个内容可编辑的 div。问题是,在字段之间切换时,如果用户点击 UIWebView,键盘会在瞬间消失。

从 UIWebView 到原生 UITextView,键盘仍然显示。

即使在点击 not contentEditable 的 UIWebView 时,键盘也会被关闭。在这种情况下,我可以将 userInteractionEnabled 转换为 false,但如果我希望它可以滚动,那仍然行不通。

这是一个演示问题的 gif:

这背后没有什么特别的代码,除了将以下 HTML 加载到 UIWebViews 中(contentEditable 被第二个删除)

<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta name="viewport" content="user-scalable=no">
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    </head>
    <body>
        <div id="editor" contentEditable="true"></div>
    </body>
</html>

【问题讨论】:

  • 这是 iOS 的本质。那么,问题出在哪里
  • 问题在于,当您在原生元素(即 UITextView 到 UITextView 或 UITextField)之间切换时,键盘不会被解除,但在这种情况下会被解除。因此,当进入 UIWebView 时,它违背了 iOS 的本质(从用户的角度来看)。

标签: ios objective-c iphone swift uiwebview


【解决方案1】:

据我所知,当键盘不再是第一响应者时,它就会被关闭。您可以使用 ...shouldEndEditing: 方法,使其返回 NO 以保持键盘可见。

希望对你有帮助

【讨论】:

  • 感谢您的回答,但我的问题更多是关于在 UIWebViews 之间切换。 UIWebViewDelegate 没有...shouldEndEditing: 不幸的是......
【解决方案2】:

事实证明,在互联网上搜索了一个星期后,我发现了一个重复的问题!我正在通过diegoreymendez 重新发布来自this post 的相关代码。

UIWebView+GUIFixes.h

#import <UIKit/UIKit.h>

@interface UIWebView (GUIFixes)

/**
 *  @brief      Wether the UIWebView will use the fixes provided by this category or not.
 */
@property (nonatomic, assign, readwrite) BOOL usesGUIFixes;

@end

UIWebView+GUIFixes.m

#import "UIWebView+GUIFixes.h"
#import <objc/runtime.h>

@implementation UIWebView (GUIFixes)

static const char* const fixedClassName = "UIWebBrowserViewMinusAccessoryView";
static Class fixClass = Nil;

- (UIView *)browserView
{
    UIScrollView *scrollView = self.scrollView;

    UIView *browserView = nil;
    for (UIView *subview in scrollView.subviews) {
        if ([NSStringFromClass([subview class]) hasPrefix:@"UIWebBrowserView"]) {
            browserView = subview;
            break;
        }
    }

    return browserView;
}

- (BOOL)delayedBecomeFirstResponder
{
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [super becomeFirstResponder];
    });

    return YES;
}

- (void)ensureFixedSubclassExistsOfBrowserViewClass:(Class)browserViewClass
{
    if (!fixClass) {
        Class newClass = objc_allocateClassPair(browserViewClass, fixedClassName, 0);
        objc_registerClassPair(newClass);

        IMP delayedFirstResponderImp = [self methodForSelector:@selector(delayedBecomeFirstResponder)];
        Method becomeFirstResponderMethod = class_getInstanceMethod(browserViewClass, @selector(becomeFirstResponder));
        method_setImplementation(becomeFirstResponderMethod, delayedFirstResponderImp);

        fixClass = newClass;
    }
}

- (BOOL)usesGUIFixes
{
    UIView *browserView = [self browserView];
    return [browserView class] == fixClass;
}

- (void)setUsesGUIFixes:(BOOL)value
{
    UIView *browserView = [self browserView];
    if (browserView == nil) {
        return;
    }

    [self ensureFixedSubclassExistsOfBrowserViewClass:[browserView class]];

    if (value) {
        object_setClass(browserView, fixClass);
    }
    else {
        Class normalClass = objc_getClass("UIWebBrowserView");
        object_setClass(browserView, normalClass);
    }

    [browserView reloadInputViews];
}

@end

不得不像这样处理 objc 运行时感觉又脏又脆弱,但据我所知,这是唯一可行的方法。

【讨论】:

  • 然而,我们最终没有使用它。它不仅超级hacky,而且在处理具有多阶段输入的语言(例如日语)时也存在一个大问题。您不能以编程方式将其设置为第一响应者并让文本输入正常工作。
  • 你最后做了什么?
  • 我真的不记得了。我认为我们从来没有真正 100% 修复它。现在看,问题依旧:/
猜你喜欢
  • 1970-01-01
  • 2020-02-09
  • 2020-05-22
  • 1970-01-01
  • 2021-03-24
  • 2011-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多