Matrosov Alexander Matrosov Alexander - 11 months ago 64
iOS Question

iOS 7 UIWebView keyboard issue

I have to remove this bar as here link but for iOS 7 this code does not work.

Answer Source

We remove this bar with some Objective C runtime trickery.

We have a class which has one method:

@interface _SwizzleHelper : NSObject @end

@implementation _SwizzleHelper

        return nil;


Once we have a web view which we want to remove the bar from, we iterate its scroll view's subviews and take the UIWebDocumentView class. We then dynamically make the superclass of the class we created above to be the subview's class (UIWebDocumentView - but we cannot say that upfront because this is private API), and replace the subview's class to our class.

#import "objc/runtime.h"    

    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));


    object_setClass(subview, newClass);

The equivalent of the above in Swift 2.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.enumerate() {
            if NSStringFromClass(view.dynamicType).hasPrefix("UIWeb") {
                subview = view

        guard subview != nil else {

        //Guard in case this method is called twice on the same webview.
        guard !(swizzledClassMapping as NSArray).containsObject(subview!.dynamicType) else {

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

        if newClass == nil {
            newClass = objc_allocateClassPair(subview!.dynamicType, className, 0)

            guard newClass != nil else {

            let method = class_getInstanceMethod(self.dynamicType, "noInputAccessoryView")
            class_addMethod(newClass!, "inputAccessoryView", method_getImplementation(method), method_getTypeEncoding(method))


            swizzledClassMapping += [newClass!]

        object_setClass(subview!, newClass!)