2013-08-03 10 views
6

Görünümün bir yerel UITextField ve bir UIWebView içerdiği bir gereksinim var. Sorun, odağı UITextView'dan UIWebView'a, klavye penceresi titreşimine (gizler ve sonra gösterir) çevirir. yani ben başka bir şekilde geçiş yaptığınızda bunun olmadığını, UIKeyboardWillHideNotification ve UIKeyboardDidShowNotificationKlavye gizlemekten nasıl kaçınılır ve odaklama UITextField ve UIWebView öğelerinden ne zaman değiştiğinde gösterilir?

var Ama. ies, sadece UIKeyboardDidShowNotification aldım

Bu titreyen efekti önlemek için herhangi bir yolu var mı?

Not: Birden çok UITextField ve UIWebView'ım varsa, bu sorun aynı türde görünümlerde olmaz.

+0

hey göstermek istediğiniz WebView'den UITextView'a geçtiğinizde klavye – Ranjit

+0

Tam olarak yok. Odak UITextView olduğunda klavye gösteriliyordu. Şimdi odağı UIWebView'e değiştiriyorum. Bu noktada titriyor. – Manoj

+0

Odak, tıklama mı demek istiyorsun? – Ranjit

cevap

8

Bu sorunu aşağıdaki koddan çözdüm. Sadece webView.usesGUIFixes = YES;'u ayarlayın ve sorununuzu çözmelidir. Ayrıca aşağıda kod UIWebView klavye için kullanılacak bir özel giriş görünümü daha ayarlayabilirsiniz:

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

Sadece siz biliyorsunuz. UITextField'ı ayrı bir 'contentEditable' div olarak web görünümüne taşıdık. Bu, bu geçici çözümün gerekmeden klavye gizleme sorunlarını çözdü. – diegoreymendez

İlgili konular