我有一个要求,其中视图包含一个本机UITextField和一个UIWebView.问题是如果我将焦点从UITextView切换到UIWebView,键盘窗口会闪烁(隐藏然后显示).
即,我得到了UIKeyboardWillHideNotification和UIKeyboardDidShowNotification
即,我得到了UIKeyboardWillHideNotification和UIKeyboardDidShowNotification
但是,当我换另一种方式时,这种情况不会发生. ies,我只得到了UIKeyboardDidShowNotification
有没有办法避免这种闪烁效应?
注意:我也注意到如果我有多个UITextField和UIWebView,这个问题不会发生在相同类型的视图中.
解决方法
我通过下面的代码解决了这个问题.只需设置webView.usesGUIFixes = YES;它应该解决你的问题.下面的代码还允许您设置用于UIWebView键盘的自定义输入视图:
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
- #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