In my program I use UIWebView with editable div for the Rich text editor. I need to remove top bar of the keyboard.
I used below code - it removes only next/previous buttons
I want to remove full top bar.
- (void)removeBar {
UIWindow *keyboardWindow = nil;
for (UIWindow *testWindow in [[UIApplication sharedApplication] windows]) {
if (![[testWindow class] isEqual:[UIWindow class]]) {
keyboardWindow = testWindow;
break;
}
}
for (UIView *possibleFormView in [keyboardWindow subviews]) {
// iOS 5 sticks the UIWebFormView inside a UIPeripheralHostView.
if ([[possibleFormView description] rangeOfString:#"UIPeripheralHostView"].location != NSNotFound) {
for (UIView *subviewWhichIsPossibleFormView in [possibleFormView subviews]) {
if ([[subviewWhichIsPossibleFormView description] rangeOfString:#"UIWebFormAccessory"].location != NSNotFound) {
[subviewWhichIsPossibleFormView removeFromSuperview];
}
}
}
}
}
I found the solution for iOS 8. You can check it here: [ iOS 8 - Remove Previous/Next/Done UIKeyboard Toolbar inside a UIWebView][1]
You may try and improve this. try call this function inside Your UIKeyboardDidShowNotification event handler.
Hope this helps...
This is the level of views in accessory:
(UIWebFormAccessory) -> (UIToolbar) -> (UIImageView,UIToolbarButton,UIToolbarButton)
-(void) removeKeyboard {
UIWindow *keyboardWindow = nil;
for (UIWindow *testWindow in [[UIApplication sharedApplication] windows]) {
if (![[testWindow class] isEqual : [UIWindow class]]) {
keyboardWindow = testWindow;
break;
}
}
// Locate UIWebFormView.
for (UIView *possibleFormView in [keyboardWindow subviews]) {
if ([[possibleFormView description] hasPrefix : #"<UIInputSetContainerView"]) {
for (UIView* peripheralView in possibleFormView.subviews) {
for (UIView* peripheralView_sub in peripheralView.subviews) {
// hides the backdrop (iOS 8)
if ([[peripheralView_sub description] hasPrefix : #"<UIKBInputBackdropView"] && peripheralView_sub.frame.size.height == 44) {
[[peripheralView_sub layer] setOpacity : 0.0];
}
// hides the accessory bar
if ([[peripheralView_sub description] hasPrefix : #"<UIWebFormAccessory"]) {
for (UIView* UIInputViewContent_sub in peripheralView_sub.subviews) {
CGRect frame1 = UIInputViewContent_sub.frame;
frame1.size.height = 0;
peripheralView_sub.frame = frame1;
UIInputViewContent_sub.frame = frame1;
[[peripheralView_sub layer] setOpacity : 0.0];
}
CGRect viewBounds = peripheralView_sub.frame;
viewBounds.size.height = 0;
peripheralView_sub.frame = viewBounds;
}
}
}
}
}
}
There is a solution for this here.
That answer includes a function called removeKeyboardTopBar which should be called on the UIKeyboardWillShowNotification.
Listen to the notification:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
On the notification, call the function after a delay. The delay is necessary to make sure that the objects exist before the function runs (since we are calling this on keyboard will show, not keyboard did show).
- (void)keyboardWillShow:(NSNotification*) notification {
[self performSelector:#selector(removeKeyboardTopBar) withObject:nil afterDelay:0];
}
From what I can tell, it looks like the keyboard has an added inputAccessoryView to the top of it. Otherwise, I'm not certain why it is appearing. Anyways, if that is the case then whatever you assign firstResponder to set their inputAccessoryView to nil:
someObjectWithFirstResponder.inputAccessoryView = nil;
EDIT: Looks like the UIWebView sets the inputAccessoryView itself, but if it is actually receiving firstResponder then you should be able to override the inputAccessoryView. If setting it to nil causing it to default back to the inputAccessoryView that you are trying to remove, then you might try setting it to an empty view:
someObjectWithFirstResponder.inputAccessoryView = [UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
EDIT This method does not work in iOS 8.0 and greater.
Related
I have a text field that I want to have a keyboard like this when user start typing:
please also see this video: https://youtu.be/iU_jocny3N0
As you can see in this video there is a "ABC" key that helps user to switch from number pad to text. and also when press "123" in text the keyboard switchs from text to number pad. I am wondering how they do this?
The only solution that I found was adding a subview to keyboard like what described here:
Adding Done Button to Only Number Pad Keyboard on iPhone
but this way may not work when user uses custom keyboards. and also do not works for switching from text to number pad.
Or as another solution I know accessoryInputView but this is not like the video. It adds a toolbar above the keyboard.
Does someone knows the solutions that is used in this video?
I have added comma button to the keyboard,
Keyboard is also a simple UIView Which contains Controls
NOTE: This is old code was working in my old project Not tested in new projects
- (void) keyboardWillShow:(NSNotification *)note {
// create custom button
dispatch_async(dispatch_get_main_queue(), ^{
// Some code
UITextField *txt = (UITextField *)[self.view findFirstResponder];
if (txt.keyboardType == UIKeyboardTypeDecimalPad) {
UIButton * btnComma = [UIButton buttonWithType:UIButtonTypeCustom];
[btnComma setTag:15000];
UIView* keyboard = [self findKeyboard];
// btnComma.frame = CGRectMake(0, 162, 126, 54);
btnComma.frame = [self findKeySizeForView:keyboard];
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"8.0")) {
[btnComma setTitleEdgeInsets:UIEdgeInsetsMake(0, 0, 20, 0)];
}
[btnComma setBackgroundColor:[UIColor colorWithHexString:#"CBD0D6"]];
btnComma.adjustsImageWhenHighlighted = NO;
[btnComma setTitle:#"." forState:UIControlStateNormal];
[btnComma setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[btnComma.titleLabel setFont:[UIFont systemFontOfSize:35.0f]];
[btnComma addTarget:self action:#selector(commaBtnTapped) forControlEvents:UIControlEventTouchUpInside];
[keyboard addSubview:btnComma];
btnComma = nil;
}
});
}
- (UIView *) viewWithPrefix:(NSString *)prefix inView:(UIView *)view {
for (UIView *subview in view.subviews) {
if ([[subview description] hasPrefix:prefix]) {
return subview;
}
}
return nil;
}
This method for finding keyboard from UIWindow
- (UIView *) findKeyboard {
for (UIWindow* window in [UIApplication sharedApplication].windows) {
UIView *inputSetContainer = [self viewWithPrefix:#"<UIInputSetContainerView" inView:window];
if (inputSetContainer) {
UIView *inputSetHost = [self viewWithPrefix:#"<UIInputSetHostView" inView:inputSetContainer];
if (inputSetHost) {
UIView *kbinputbackdrop = [self viewWithPrefix:#"<_UIKBCompatInput" inView:inputSetHost];
if (kbinputbackdrop) {
UIView *theKeyboard = [self viewWithPrefix:#"<UIKeyboard" inView:kbinputbackdrop];
return theKeyboard;
}
}
}
}
return nil;
}
and For finding size of bottom right button
- (CGRect ) findKeySizeForView:(UIView *)view {
if (view != nil) {
UIView *uiKeyboardImpl = [self viewWithPrefix:#"<UIKeyboardImpl" inView:view];
if (uiKeyboardImpl != nil) {
UIView *uiKeyboardLayoutStar = [self viewWithPrefix:#"<UIKeyboardLayoutStar" inView:uiKeyboardImpl];
if (uiKeyboardLayoutStar != nil) {
UIView *uiKBKeyplaneView = [self viewWithPrefix:#"<UIKBKeyplaneView" inView:uiKeyboardLayoutStar];
if (uiKBKeyplaneView != nil) {
for (view in [uiKBKeyplaneView subviews]) {
CGPoint pointOrigin = view.layer.frame.origin;
if (pointOrigin.x <= 0 && pointOrigin.y == uiKBKeyplaneView.frame.size.height - view.frame.size.height && [[view description] hasPrefix:#"<UIKBKeyView"])
return view.layer.frame;
}
}
}
}
}
return CGRectZero;
}
I am using custom keyboard for webview by hiding the default keyboard. But my code is crashing whenever I tap on inputbox. It says
-[UITextInteractionAssistant containerIsTextField]: message sent to deallocated
After a lot of debugging I found out that [self.view endEditing:YES]; is reposnsible for UITextInteractionAssistant.
Can anyone help in this?
Help in advance!!!
// register for keyboard show event
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
hiding UIWebviewAccessary
-(void)keyboardWillShow:(NSNotification *)note {
[self.view endEditing:YES];
[self removeBar];
[self performSelector:#selector(adjustFrame) withObject:nil afterDelay:0.03];
}
- (void)adjustFrame {
[self.webView stringByEvaluatingJavaScriptFromString:#"window.scroll(0,0)"];
}
- (void)removeBar {
// Locate non-UIWindow.
UIWindow *keyboardWindow = nil;
for (UIWindow *testWindow in [[UIApplication sharedApplication] windows]) {
if (![[testWindow class] isEqual:[UIWindow class]]) {
keyboardWindow = testWindow;
break;
}
}
// Locate UIWebFormView.
for (UIView *possibleFormView in [keyboardWindow subviews]) {
// iOS 5 sticks the UIWebFormView inside a UIPeripheralHostView.
if ([[possibleFormView description] rangeOfString:#"UIPeripheralHostView"].location != NSNotFound) {
for (UIView *subviewWhichIsPossibleFormView in [possibleFormView subviews]) {
if ([[subviewWhichIsPossibleFormView description] rangeOfString:#"UIWebFormAccessory"].location != NSNotFound) {
[subviewWhichIsPossibleFormView removeFromSuperview];
}
}
}
}
}
I am pretty new to web development, my project is using Jquery-mobile, Phonegap and compass (scss).
By default, the keyboard showing up when an input field gets focus, is a keyboard containing a sort of top bar with fields navigation abilities. I would like to get rid of this navigation bar, and display the simplest keyboard available in iOS. I tried enclosing my objects in a form or without a form tag, without success. I don't have any clue how to achieve this, nore if it is possible :/
Thx for any advice!
If you hit this problem, make sure to head over to https://bugreport.apple.com and duplicate rdar://9844216
To remove the bar you should dive into the objective-c code.
This is the code that I use: (inside the controller that contains your UIWebview add the following code)
First add an observer to receive the notification for the keyboard :
-(void)viewWillAppear:(BOOL)animated{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
}
- (void)keyboardWillShow:(NSNotification *)note {
[self performSelector:#selector(removeBar) withObject:nil afterDelay:0];
}
- (void)removeBar {
// Locate non-UIWindow.
UIWindow *keyboardWindow = nil;
for (UIWindow *testWindow in [[UIApplication sharedApplication] windows]) {
if (![[testWindow class] isEqual:[UIWindow class]]) {
keyboardWindow = testWindow;
break;
}
}
// Locate UIWebFormView.
for (UIView *formView in [keyboardWindow subviews]) {
// iOS 5 sticks the UIWebFormView inside a UIPeripheralHostView.
if ([[formView description] rangeOfString:#"UIPeripheralHostView"].location != NSNotFound) {
for (UIView *subView in [formView subviews]) {
if ([[subView description] rangeOfString:#"UIWebFormAccessory"].location != NSNotFound) {
// remove the input accessory view
[subView removeFromSuperview];
}
else if([[subView description] rangeOfString:#"UIImageView"].location != NSNotFound){
// remove the line above the input accessory view (changing the frame)
[subView setFrame:CGRectZero];
}
}
}
}
}
I was working on iOS 7.0 and fixed it with the following code on UIWebView
-(void)removeExtraBar
{
UIWindow *keyboardWindow = nil;
for (UIWindow *testWindow in [[UIApplication sharedApplication] windows]) {
if (![[testWindow class] isEqual:[UIWindow class]]) {
keyboardWindow = testWindow;
break;
}
}
for (UIView *possibleFormView in [keyboardWindow subviews]) {
if ([[possibleFormView description] rangeOfString:#"UIPeripheralHostView"].location != NSNotFound) {
for (UIView *subviewWhichIsPossibleFormView in [possibleFormView subviews]) {
if ([[subviewWhichIsPossibleFormView description] rangeOfString:#"UIWebFormAccessory"].location != NSNotFound) {
[subviewWhichIsPossibleFormView removeFromSuperview];
}
else if([[subviewWhichIsPossibleFormView description] rangeOfString:#"UIKBInputBackdropView"].location != NSNotFound) {
[subviewWhichIsPossibleFormView removeFromSuperview];
}
}
}
}
}
This works for me with the UIWebView keyboard issue on iOS 7.0
I have created by custom UIButton for iPad application.
Now for specific reasons, I want to hide those buttons. To do that I am using following code:
NSMutableArray *viewArray = [[NSMutableArray alloc] init];
// Get all the windows
for (UIWindow *window in [[UIApplication sharedApplication] windows])
{
// check for main screen
if (![window respondsToSelector:#selector(screen)] ||
[window screen] == [UIScreen mainScreen])
{
// check for all the subviews available in window
for (UIView * view in [window subviews]) {
// check whether it supports this method
if ([view respondsToSelector:#selector(isKindOfClass:)]) {
// type cast to button
// UIButton *btn = (UIButton *)view;
// if its type of my custom button class
if ([[view class] isKindOfClass:[DINNextLTProBoldButton class]]) {
// hide view and add to array
[view setHidden:YES];
[viewArray addObject:view];
}
}
}
}
}
But I am not able to get my custom buttons in this array. It stays empty only even thought the view which is being appeared on window/screen have those buttons.
Where I am going wrong? Please guide me.
try this (untested, but it gives the basic idea)
- (void)hideViewOfClass:(Class)clazz inHeirarchyOfView:(UIView *)view
{
for (UIView *subview in [view subviews])
{
if ([subview isKindOfClass:clazz])
subview.hidden = YES;
else
[self hideViewOfClass:clazz inHeirarchyOfView:subview];
}
}
call this function at first like:
for (UIWindow *window in [[UIApplication sharedApplication] windows])
[self hideViewOfClass:[DINNextLTProBoldButton class] inHeirarchyOfView:window];
When the UIWebView displays the keyboard, there is a small toolbar at the top (accessory item) that has the buttons "done, previous, next"
Currently, I'm using the following as a workaround to remove this toolbar:
https://gist.github.com/2048571
However, I'm concerned this might not work in future version of iOS. Is there a better way to be doing this?
First, listen keyboard events:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
when keyboard will show,remove the toolbar:
- (void)keyboardWillShow:(NSNotification *)note {
[self performSelector:#selector(removeBar) withObject:nil afterDelay:0];
}
the removeBar is as follows:
- (void)removeBar {
// Locate non-UIWindow.
UIWindow *keyboardWindow = nil;
for (UIWindow *testWindow in [[UIApplication sharedApplication] windows]) {
if (![[testWindow class] isEqual:[UIWindow class]]) {
keyboardWindow = testWindow;
break;
}
}
// Locate UIWebFormView
for (UIView *possibleFormView in [keyboardWindow subviews]) {
if ([[possibleFormView description] hasPrefix:#"<UIPeripheralHostView"]) {
for (UIView* peripheralView in [possibleFormView subviews]) {
// hides the backdrop (iOS 7)
if ([[peripheralView description] hasPrefix:#"<UIKBInputBackdropView"]) {
//skip the keyboard background....hide only the toolbar background
if ([peripheralView frame].origin.y == 0){
[[peripheralView layer] setOpacity:0.0];
}
}
// hides the accessory bar
if ([[peripheralView description] hasPrefix:#"<UIWebFormAccessory"]) {
// remove the extra scroll space for the form accessory bar
UIScrollView *webScroll;
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 5.0) {
webScroll = [[self webView] scrollView];
} else {
webScroll = [[[self webView] subviews] lastObject];
}
CGRect newFrame = webScroll.frame;
newFrame.size.height += peripheralView.frame.size.height;
webScroll.frame = newFrame;
// remove the form accessory bar
[peripheralView removeFromSuperview];
}
// hides the thin grey line used to adorn the bar (iOS 6)
if ([[peripheralView description] hasPrefix:#"<UIImageView"]) {
[[peripheralView layer] setOpacity:0.0];
}
}
}
}
}
Reference: https://github.com/don/KeyboardToolbarRemover/blob/master/src/ios/KeyboardToolbarRemover.m