问题描述
我要求视图包含一个本机UITextField和一个UIWebView。问题是如果我将焦点从UITextView切换到UIWebView,键盘窗口会闪烁(隐藏然后显示)。
ie,我得到了UIKeyboardWillHideNotification和UIKeyboardDidShowNotification
I have a requirement in which the view contains one native UITextField and one UIWebView. The issue is if I switch the focus from UITextView to UIWebView, the keyboard window flicker(hides and then shows).ie, I got UIKeyboardWillHideNotification and UIKeyboardDidShowNotification
但是,当我切换到另一个方向时,这不会发生。 ies,我只得到UIKeyboardDidShowNotification
But, this is not happening when I switch the other way. ies, I got only UIKeyboardDidShowNotification
有没有办法避免这种闪烁效应?
Is there any way to avoid this flickering effect?
注意:我也是通知如果我有多个UITextField和UIWebView,这个问题不会发生在相同类型的视图中。
Note: I also notices if I have multiple UITextField and UIWebView, this issue is not happening with the same type of views.
推荐答案
我已通过以下代码解决了这个问题。只需设置 webView.usesGUIFixes = YES;
,它就可以解决您的问题。下面的代码还允许您设置用于UIWebView键盘的自定义输入视图:
I've solved this problem through the code below. Simply set webView.usesGUIFixes = YES;
and it should solve your problem. The code below also lets you set a custom input view to use for the UIWebView keyboard:
UIWebView + GUIFixes.h
UIWebView+GUIFixes.h
#import <UIKit/UIKit.h>
@interface UIWebView (GUIFixes)
/**
* @brief The custom input accessory view.
*/
@property (nonatomic, strong, readwrite) UIView* customInputAccessoryView;
/**
* @brief Wether the UIWebView will use the fixes provided by this category or not.
*/
@property (nonatomic, assign, readwrite) BOOL usesGUIFixes;
@end
UIWebView + GUIFixes.m
UIWebView+GUIFixes.m
#import "UIWebView+GUIFixes.h"
#import <objc/runtime.h>
@implementation UIWebView (GUIFixes)
static const char* const kCustomInputAccessoryView = "kCustomInputAccessoryView";
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;
}
- (id)methodReturningCustomInputAccessoryView
{
UIView* view = [self performSelector:@selector(originalInputAccessoryView) withObject:nil];
if (view) {
UIView* parentWebView = self.superview;
while (parentWebView && ![parentWebView isKindOfClass:[UIWebView class]])
{
parentWebView = parentWebView.superview;
}
UIView* customInputAccessoryView = [(UIWebView*)parentWebView customInputAccessoryView];
if (customInputAccessoryView) {
view = customInputAccessoryView;
}
}
return view;
}
- (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);
IMP oldImp = class_getMethodImplementation(browserViewClass, @selector(inputAccessoryView));
class_addMethod(newClass, @selector(originalInputAccessoryView), oldImp, "@@:");
IMP newImp = [self methodForSelector:@selector(methodReturningCustomInputAccessoryView)];
class_addMethod(newClass, @selector(inputAccessoryView), newImp, "@@:");
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];
}
- (UIView*)customInputAccessoryView
{
return objc_getAssociatedObject(self, kCustomInputAccessoryView);
}
- (void)setCustomInputAccessoryView:(UIView*)view
{
objc_setAssociatedObject(self,
kCustomInputAccessoryView,
view,
OBJC_ASSOCIATION_RETAIN);
}
@end
这篇关于如何避免键盘隐藏和显示何时焦点从UITextField和UIWebView更改?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!