-
-
Save bjhomer/2048571 to your computer and use it in GitHub Desktop.
| #import <objc/runtime.h> | |
| #import <UIKit/UIKit.h> | |
| @interface UIWebView (HackishAccessoryHiding) | |
| @property (nonatomic, assign) BOOL hackishlyHidesInputAccessoryView; | |
| @end | |
| @implementation UIWebView (HackishAccessoryHiding) | |
| static const char * const hackishFixClassName = "UIWebBrowserViewMinusAccessoryView"; | |
| static Class hackishFixClass = Nil; | |
| - (UIView *)hackishlyFoundBrowserView { | |
| 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)methodReturningNil { | |
| return nil; | |
| } | |
| - (void)ensureHackishSubclassExistsOfBrowserViewClass:(Class)browserViewClass { | |
| if (!hackishFixClass) { | |
| newClass = objc_allocateClassPair(browserViewClass, hackishFixClassName, 0); | |
| IMP nilImp = [self methodForSelector:@selector(methodReturningNil)]; | |
| class_addMethod(newClass, @selector(inputAccessoryView), nilImp, "@@:"); | |
| objc_registerClassPair(newClass); | |
| hackishFixClass = newClass; | |
| } | |
| } | |
| - (BOOL) hackishlyHidesInputAccessoryView { | |
| UIView *browserView = [self hackishlyFoundBrowserView]; | |
| return [browserView class] == hackishFixClass; | |
| } | |
| - (void) setHackishlyHidesInputAccessoryView:(BOOL)value { | |
| UIView *browserView = [self hackishlyFoundBrowserView]; | |
| if (browserView == nil) { | |
| return; | |
| } | |
| [self ensureHackishSubclassExistsOfBrowserViewClass:[browserView class]]; | |
| if (value) { | |
| object_setClass(browserView, hackishFixClass); | |
| } | |
| else { | |
| Class normalClass = objc_getClass("UIWebBrowserView"); | |
| object_setClass(browserView, normalClass); | |
| } | |
| [browserView reloadInputViews]; | |
| } | |
| @end |
| #import <objc/runtime.h> | |
| #import <UIKit/UIKit.h> | |
| @interface UIWebView (HackishAccessoryHiding) | |
| @property (nonatomic, assign) BOOL hackishlyHidesInputAccessoryView; | |
| @end | |
| @implementation UIWebView (HackishAccessoryHiding) | |
| static const char * const hackishFixClassName = "UIWebBrowserViewMinusAccessoryView"; | |
| static Class hackishFixClass = Nil; | |
| - (UIView *)hackishlyFoundBrowserView { | |
| 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)methodReturningNil { | |
| return nil; | |
| } | |
| - (void)ensureHackishSubclassExistsOfBrowserViewClass:(Class)browserViewClass { | |
| if (!hackishFixClass) { | |
| Class newClass = objc_allocateClassPair(browserViewClass, hackishFixClassName, 0); | |
| IMP nilImp = [self methodForSelector:@selector(methodReturningNil)]; | |
| class_addMethod(newClass, @selector(inputAccessoryView), nilImp, "@@:"); | |
| objc_registerClassPair(newClass); | |
| hackishFixClass = newClass; | |
| } | |
| } | |
| - (BOOL) hackishlyHidesInputAccessoryView { | |
| UIView *browserView = [self hackishlyFoundBrowserView]; | |
| return [browserView class] == hackishFixClass; | |
| } | |
| - (void) setHackishlyHidesInputAccessoryView:(BOOL)value { | |
| UIView *browserView = [self hackishlyFoundBrowserView]; | |
| if (browserView == nil) { | |
| return; | |
| } | |
| [self ensureHackishSubclassExistsOfBrowserViewClass:[browserView class]]; | |
| if (value) { | |
| object_setClass(browserView, hackishFixClass); | |
| } | |
| else { | |
| Class normalClass = objc_getClass("UIWebBrowserView"); | |
| object_setClass(browserView, normalClass); | |
| } | |
| [browserView reloadInputViews]; | |
| } | |
| @end |
I used a variation of this to get rid of the inputView entirely, nice work.
I seems like does not work on IOS 6.x.
how to get rid of inputView?
@bjhomer
I'm afraid I'm very inexperienced within Objective-C, I've created a .m file (UIWebViewFormAssistantHack.m) with this contents, and although you explained that the property should be accessible, I can't seem to reference it from the viewDidLoad scope using self.webView.sethackishlyHidesInputAccessoryView(YES); (or self.webView.hackishlyHidesInputAccessoryView = YES for that matter)
Would you be so kind to help me clarify what I am doing wrong?
@zhangchuqi
Just replace references to "inputAccessoryView" with "inputView" in the above code. And instead of returning nil (which I think in the case of inputView will still cause the default keyboard to show) you'll want to return an empty UIView.
@AskeG
You probably know this by now, but you need to include the category's .h file in header of your view controller.
I think this is way much better than https://github.com/don/KeyboardToolbarRemover
You can eliminate [browserView reloadInputViews];
I didn't see a license on the website. Would you be willing to license the code under the MIT (http://opensource.org/licenses/MIT) or BSD (http://opensource.org/licenses/BSD-2-Clause) license?
hi ! can we custom inputView for UIWebview with this solutions?
I've made a Cocoapod based on your solution.
I also posted a gist that allows to customize OR disable the inputAccessoryView:
https://gist.github.com/kgaidis/5f9a8c7063b687cc3946fad6379c1a66
how do i do this for wkwebview
@tinhbka
replace UIWebView's inputView :
-(id)methodReturningKeyboard {
return [[JSInputView alloc] initWithFrame:CGRectZero];
}
- (void)ensureHackishSubclassExistsOfBrowserViewClass:(Class)browserViewClass {
if (!hackishFixClass) {
Class newClass = objc_allocateClassPair(browserViewClass, hackishFixClassName, 0);
newClass = objc_allocateClassPair(browserViewClass, hackishFixClassName, 0);
IMP keyboardImp = [self methodForSelector:@selector(methodReturningKeyboard)];
class_addMethod(newClass, @selector(inputView), keyboardImp, "@@:");
objc_registerClassPair(newClass);
hackishFixClass = newClass;
}
}
Based on Mike Ash comments http://www.mikeash.com/pyblog/friday-qa-2010-11-6-creating-classes-at-runtime-in-objective-c.html, would it be better to do the following?
@devinfoley
I think some apps like Evernote, which is probably using a UIWebView to show/edit notes, may use something similar to this Gist.