当焦点从UITextField和UIWebView更改时,如何避免键盘隐藏和显示?

我有一个要求,其中视图包含一个本机UITextField和一个UIWebView。 问题是如果我将焦点从UITextView切换到UIWebView,键盘窗口会闪烁(隐藏然后显示)。 即,我得到了UIKeyboardWillHideNotification和UIKeyboardDidShowNotification

但是,当我换另一种方式时,这种情况不会发生。 ies,我只得到了UIKeyboardDidShowNotification

有没有办法避免这种闪烁效应?

注意:我也注意到如果我有多个UITextField和UIWebView,这个问题不会发生在相同类型的视图中。

我通过下面的代码解决了这个问题。 只需设置webView.usesGUIFixes = YES; 它应该解决你的问题。 下面的代码还允许您设置用于UIWebView键盘的自定义输入视图:

UIWebView的+ GUIFixes.h

 #import  @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

 #import "UIWebView+GUIFixes.h" #import  @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