Подтвердить что ты не робот

Проблема с клавиатурой iOS 7 UIWebView

Мне нужно удалить этот бар, как здесь ссылка, но для iOS 7 этот код не работает.

4b9b3361

Ответ 1

Мы удаляем эту панель с некоторыми обходами Objective C.

У нас есть класс, который имеет один метод:

@interface _SwizzleHelper : NSObject @end

@implementation _SwizzleHelper

    -(id)inputAccessoryView
    {
        return nil;
    }

@end

Как только у нас появится веб-представление, с которого мы хотим удалить панель, мы перебираем его подпрограммы просмотра прокрутки и берем класс UIWebDocumentView. Затем мы динамически делаем суперкласс класса, который мы создали выше, как класс subview (UIWebDocumentView - но мы не можем сказать, что это заранее, потому что это частный API), и замените класс subview на наш класс.

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

Эквивалент приведенного выше в 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!)
    }
}

Ответ 3

Я столкнулся с этим замечательным решением, но мне также нужно было вернуть inputAccessoryView. Я добавил этот метод:

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

Кажется, он работает по назначению без побочных эффектов, но я не могу избавиться от чувства, что мои штаны горят.

Если вы хотите, чтобы решение Leo Natan работало с WKWebView вместо UIWebView, просто измените префикс от "UIWeb" до "WKContent".

Ответ 4

Я создал суть, чтобы выполнить это: https://gist.github.com/kgaidis/5f9a8c7063b687cc3946fad6379c1a66

Это категория UIWebView, где все, что вы делаете, это изменение свойства customInputAccessoryView:

@interface UIWebView (CustomInputAccessoryView)

@property (strong, nonatomic) UIView *customInputAccessoryView;

@end

Вы можете установить его на nil, чтобы удалить его, или вы можете установить для него новый вид, чтобы изменить его.

Имейте в виду, что это также использует частный API, поэтому используйте его на свой страх и риск, но, похоже, многие приложения делают подобные вещи, тем не менее.