2013-09-26 220 views
13

Tôi phải xóa thanh này ở đây link nhưng đối với iOS 7 mã này không hoạt động.Vấn đề bàn phím UIWebView iOS 7

+0

Tôi đã thêm một khoản tiền thưởng nhỏ cho câu trả lời công nghệ cao đáng kinh ngạc này, cảm ơn mọi người, Leo !! – Fattie

+1

@JoeBlow Cảm ơn Joe! Chỉ cần nhận thấy bình luận của bạn ở đây. –

Trả lời

25

Chúng tôi xóa thanh này bằng một số thủ thuật thời gian chạy Objective C.

Chúng tôi có một lớp học trong đó có một phương pháp:

@interface _SwizzleHelper : NSObject @end 

@implementation _SwizzleHelper 

    -(id)inputAccessoryView 
    { 
     return nil; 
    } 

@end 

Một khi chúng ta có một cái nhìn web mà chúng tôi muốn loại bỏ các thanh từ, chúng ta lặp subviews xem di chuyển của nó và lấy lớp UIWebDocumentView. Sau đó chúng ta tạo động cho lớp cha của lớp mà chúng ta đã tạo ở trên để trở thành lớp của lớp con (UIWebDocumentView - nhưng chúng ta không thể nói trước vì đây là API riêng), và thay thế lớp của lớp con thành lớp của chúng ta.

#import "objc/runtime.h"  

-(void)__removeInputAccessoryView 
{ 
    UIView* subview; 

    for (UIView* view in self.scrollView.subviews) { 
     if([[view.class description] hasPrefix:@"UIWeb"]) 
      subview = view; 
    } 

    if(subview == nil) return; 

    NSString* name = [NSString stringWithFormat:@"%@_SwizzleHelper", subview.class.superclass]; 
    Class newClass = NSClassFromString(name); 

    if(newClass == nil) 
    { 
     newClass = objc_allocateClassPair(subview.class, [name cStringUsingEncoding:NSASCIIStringEncoding], 0); 
     if(!newClass) return; 

     Method method = class_getInstanceMethod([_SwizzleHelper class], @selector(inputAccessoryView)); 
     class_addMethod(newClass, @selector(inputAccessoryView), method_getImplementation(method), method_getTypeEncoding(method)); 

     objc_registerClassPair(newClass); 
    } 

    object_setClass(subview, newClass); 
} 

Tương đương trên trong Swift 3.0:

import UIKit 
import ObjectiveC 

var swizzledClassMapping = [AnyClass]() 

extension UIWebView { 
    func noInputAccessoryView() -> UIView? { 
     return nil 
    } 

    public func removeInputAccessoryView() { 
     var subview: AnyObject? 

     for (_, view) in scrollView.subviews.enumerated() { 
      if NSStringFromClass(type(of: view)).hasPrefix("UIWeb") { 
       subview = view 
      } 
     } 

     guard subview != nil else { 
      return 
     } 

     //Guard in case this method is called twice on the same webview. 
     guard !(swizzledClassMapping as NSArray).contains(type(of: subview!)) else { 
      return; 
     } 

     let className = "\type(of: subview!)_SwizzleHelper" 
     var newClass : AnyClass? = NSClassFromString(className) 

     if newClass == nil { 
      newClass = objc_allocateClassPair(type(of: subview!), className, 0) 

      guard newClass != nil else { 
       return; 
      } 

      let method = class_getInstanceMethod(type(of: self), #selector(UIWebView.noInputAccessoryView)) 
      class_addMethod(newClass!, #selector(getter: UIResponder.inputAccessoryView), method_getImplementation(method), method_getTypeEncoding(method)) 

      objc_registerClassPair(newClass!) 

      swizzledClassMapping += [newClass!] 
     } 

     object_setClass(subview!, newClass!) 
    } 
} 
+0

giải pháp này cho quy trình phê duyệt của App Store như thế nào? bạn đã có một ứng dụng được chấp thuận có mã này chưa? – Larry

+3

Có, chúng tôi có ứng dụng của chúng tôi với một mã tương tự như thế này và nó đã được phê duyệt. –

+0

'subview' được định nghĩa như thế nào?tôi đã sử dụng tiểu trình 'NSObject * subview = [[viewView [webView scrollView]] [0];' (thực ra là đối tượng 'UIWebBrowserView' và subview duy nhất trong subviews của scrollView) và objc bị lỗi với:' [UIWebDocumentView_SwizzleHelper autoFillDelegate]: unrecognized bộ chọn được gửi tới trường hợp 0xa8cba00'. – Larry

0

Tôi đã đi qua giải pháp tuyệt vời này, nhưng tôi cần để có được những inputAccessoryView lại là tốt. Tôi đã thêm phương pháp này:

- (void)__addInputAccessoryView { 

    UIView* subview; 

    for (UIView* view in self.scrollView.subviews) { 

     if([[view.class description] hasSuffix:@"SwizzleHelper"]) 
      subview = view; 
    } 

    if(subview == nil) return; 

    Class newClass = subview.superclass; 

    object_setClass(subview, newClass); 
} 

Nó dường như hoạt động như dự định không có tác dụng phụ, nhưng tôi không thể loại bỏ cảm giác quần của tôi đang cháy.

Nếu bạn muốn giải pháp của Leo Natan hoạt động với WKWebView thay vì UIWebView, chỉ cần thay đổi tiền tố từ "UIWeb" thành "WKContent".

+0

hi người đàn ông cảm ơn cho câu trả lời nhưng đó là câu hỏi cũ) nhưng tôi sẽ trở lại nhiệm vụ đó tôi sẽ kiểm tra nó –

0

Tôi tạo ra một ý chính để thực hiện điều này: https://gist.github.com/kgaidis/5f9a8c7063b687cc3946fad6379c1a66

Đó là một loại UIWebView nơi tất cả các bạn cần làm là thay đổi customInputAccessoryView tài sản:

@interface UIWebView (CustomInputAccessoryView) 

@property (strong, nonatomic) UIView *customInputAccessoryView; 

@end 

Bạn có thể thiết lập nó để nil để xoá bỏ nó hoặc bạn có thể đặt chế độ xem mới trên đó để thay đổi.

Xin lưu ý, điều này cũng sử dụng API riêng tư, vì vậy hãy tự chịu rủi ro, nhưng có vẻ như rất nhiều ứng dụng cũng làm những việc tương tự.