2015-11-22 1 views
5

Я пытаюсь в течение нескольких дней получить this, преобразованный в Swift, не имея при этом большого количества фона.Удаление WKWebView Прикладная панель в Swift

Это то, что у меня есть до сих пор ... и я искал Google, не зная, что искать, чтобы быть более конкретным. Не могли бы вы пролить свет на то, что я делаю неправильно? Благодаря

Update:

Я aded в Objective-C тег просто так больше людей, которые имеют отношение к этой теме может быть в состоянии видеть его, и мы надеемся получить ответ.

enter image description here

+0

Как вы решили это подробно, пожалуйста? – socca1157

ответ

9

Ответ Майкла Даутерманна имеет все правильно, но для того, чтобы скрыть панель аксессуаров, вам нужно выполнить метод inputAccessoryView() класса UIView с помощью inputAccessoryView() класса _NoInputAccessoryView. Я только что добавил пару дополнительных строк к коду, который выполняет эту работу по методу swizzling.

Сначала вам нужно фальшивый класс поменять с

final class FauxBarHelper: NSObject { 
    var inputAccessoryView: AnyObject? { return nil } 
} 

Затем создайте этот метод в контроллере класса

/// Removes the keyboard accessory view from the web view 
/// Source: http://stackoverflow.com/a/32620344/308315/http://stackoverflow.com/a/33939584/308315 
func _removeInputAccessoryView(webView: UIWebView) { 
    var targetView: UIView? = nil 

    for view in webView.scrollView.subviews { 
     if String(describing: type(of: view)).hasPrefix("WKContent") { 
      targetView = view 
     } 
    } 

    guard let target = targetView else { return } 

    let noInputAccessoryViewClassName = "\(target.superclass!)_NoInputAccessoryView" 
    var newClass: AnyClass? = NSClassFromString(noInputAccessoryViewClassName) 
    if newClass == nil { 
     let targetClass: AnyClass = object_getClass(target) 
     newClass = objc_allocateClassPair(targetClass, noInputAccessoryViewClassName.cString(using: String.Encoding.ascii)!, 0) 
    } 

    let originalMethod = class_getInstanceMethod(FauxBarHelper.self, #selector(getter: FauxBarHelper.inputAccessoryView)) 
    class_addMethod(newClass!.self, #selector(getter: FauxBarHelper.inputAccessoryView), method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)) 
    object_setClass(target, newClass) 
} 

HTH;)

+0

Вы мужчина йогиш! – Eduard

+0

Я бы с удовольствием посмотрел учебник по этой реализации ... – socca1157

+1

@ socca1157 Спасибо за предложение, я попытаюсь написать один на Medium, я буду держать вас в курсе :) – iamyogish

3

Этот фрагмент кода должен получить вас над вопросом:

class _NoInputAccessoryView: NSObject { 

    func removeInputAccessoryViewFromWKWebView(webView: WKWebView) { 
     // make sure to make UIView an optional here... 
     var targetView: UIView? = nil 
     for view in webView.scrollView.subviews { 
      if String(view.dynamicType).hasPrefix("WKContent") { 
       targetView = view 
      } 
     } 

     // only optionals can be nil 
     if targetView == nil { 
      return 
     } 

     let noInputAccessoryViewClassName = "\(targetView!.superclass)_NoInputAccessoryView" 
     var newClass : AnyObject? = NSClassFromString(noInputAccessoryViewClassName) 
     if newClass == nil { 
      let uiViewClass : AnyClass = object_getClass(targetView!) 
      newClass = objc_allocateClassPair(uiViewClass, noInputAccessoryViewClassName.cStringUsingEncoding(NSASCIIStringEncoding)!, 0) 
     } 
    } 

Вы можете также использовать «String(view.dynamicType)», чтобы получить имя класса объекта, вы смотрите, as I noticed via this answer as I was researching the way to solve your problem.

Использование hasPrefix как в Objective-C, так и в Swift действительно опасно и, возможно, лучший способ скрытия клавиатуры можно найти для производственного кода?

+0

Я сделал изменения и небольшое исправление, которое я редактировал, но теперь я получаю [это] (http://i.imgur.com/1q9UzPi.png). Я пробовал добавить 'newClass: AnyClass? = NSClassFromString', который решает предупреждение и сравнение «newClass == nil», но затем он оставляет меня с третьей ошибкой: «Невозможно преобразовать значение типа UIView в ожидаемый тип AnyClass!» – Eduard

+0

Я внедрил корректировку кода. .. попробуйте сейчас. –

+0

еще один глупый вопрос, как применить этот класс поверх объекта webview? Я просто новый и глупый .. извините – Eduard

1

Вот немного безопаснее (нет небезопасная развертка), которая работает с Swift 4 и (по крайней мере) iOS 9. 11.

fileprivate final class InputAccessoryHackHelper: NSObject { 
    @objc var inputAccessoryView: AnyObject? { return nil } 
} 

extension WKWebView { 
    func hack_removeInputAccessory() { 
     guard let target = scrollView.subviews.first(where: { 
      String(describing: type(of: $0)).hasPrefix("WKContent") 
     }), let superclass = target.superclass else { 
      return 
     } 

     let noInputAccessoryViewClassName = "\(superclass)_NoInputAccessoryView" 
     var newClass: AnyClass? = NSClassFromString(noInputAccessoryViewClassName) 

     if newClass == nil, let targetClass = object_getClass(target), let classNameCString = noInputAccessoryViewClassName.cString(using: .ascii) { 
      newClass = objc_allocateClassPair(targetClass, classNameCString, 0) 

      if let newClass = newClass { 
       objc_registerClassPair(newClass) 
      } 
     } 

     guard let noInputAccessoryClass = newClass, let originalMethod = class_getInstanceMethod(InputAccessoryHackHelper.self, #selector(getter: InputAccessoryHackHelper.inputAccessoryView)) else { 
      return 
     } 
     class_addMethod(noInputAccessoryClass.self, #selector(getter: InputAccessoryHackHelper.inputAccessoryView), method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)) 
     object_setClass(target, noInputAccessoryClass) 
    } 
} 
Смежные вопросы