2013-08-03 10 views
6

Mam wymóg, w którym widok zawiera jeden macierzysty UITextField i jeden UIWebView. Problem polega na tym, że jeśli przełączę fokus z UITextView na UIWebView, migocze okno klawiatury (ukrywa i pokazuje). tzn. Mam UIKeyboardWillHideNotification i UIKeyboardDidShowNotificationJak uniknąć ukrywania klawiatury i pokazywania, gdy fokus zmienia się z UITextField i UIWebView?

Ale to się nie dzieje, kiedy przełączam się w drugą stronę. ies, mam tylko UIKeyboardDidShowNotification

Czy istnieje sposób na uniknięcie tego efektu migotania?

Uwaga: Zauważyłem również, że jeśli mam wiele UITextField i UIWebView, ten problem nie występuje z tym samym typem widoków.

+0

hej chcesz pokazać klawiatura po przejściu z webView do UITextView? – Ranjit

+0

Nie dokładnie. Klawiatura była wyświetlana, gdy fokus znajduje się w UITextView. Teraz przełączam fokus na UIWebView. W tym momencie migocze. – Manoj

+0

przez focus, masz na myśli kliknięcie? – Ranjit

Odpowiedz

8

Rozwiązałem ten problem za pomocą poniższego kodu. Po prostu ustaw webView.usesGUIFixes = YES; i powinno to rozwiązać twój problem. Poniższy kod również pozwala ustawić niestandardowego widoku wejściowy do wykorzystania na klawiaturze 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 
+0

Po prostu, żebyście wiedzieli. Ostatecznie przenieśliśmy UITextField do widoku sieciowego jako oddzielny div "contentEditable". To rozwiązało problemy z ukrywaniem klawiatury bez potrzeby obejścia tego problemu. – diegoreymendez

Powiązane problemy