点击 UIWebViews 时键盘消失
Keyboard gets dismissed when tapping into UIWebViews
我有一些用于富文本编辑的 UIWebView。他们有一个 contentEditable 的 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>
据我所知,当键盘不再是第一响应者时,键盘将被关闭。您可以使用 ...shouldEndEditing:
方法,使其返回 NO 以保持键盘可见。
希望对您有所帮助
事实证明,在为这个问题和相关问题在互联网上搜索了一个星期之后,我最终发现了一个重复的问题!我正在从 this post by diegoreymendez.
重新发布相关代码
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 运行时感觉很肮脏和脆弱,但据我所知,这是唯一可行的方法。
我有一些用于富文本编辑的 UIWebView。他们有一个 contentEditable 的 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>
据我所知,当键盘不再是第一响应者时,键盘将被关闭。您可以使用 ...shouldEndEditing:
方法,使其返回 NO 以保持键盘可见。
希望对您有所帮助
事实证明,在为这个问题和相关问题在互联网上搜索了一个星期之后,我最终发现了一个重复的问题!我正在从 this post by diegoreymendez.
重新发布相关代码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 运行时感觉很肮脏和脆弱,但据我所知,这是唯一可行的方法。