I am using below code to get the keyboard location from view & add DONE button on it.But in ios 8 it is not able to get keyboard location & hence not add DONE butto
The below code is for showing "DONE" button on NumberPad iOS 8 also. I run this code in XCode-5.1.1 with iOS 6/7/8 devices. Its working perfectly.
I take the refrence from this link Can't find keyplane that supports type 4 for keyboard iPhone-Portrait-NumberPad given some code for add button on Number keyboard.
@property (nonatomic, retain) UIButton *doneButton;
AddButton
- (void)addButtonToKeyboard
{
if (!self.doneButton)
{
self.doneButton = [UIButton buttonWithType:UIButtonTypeCustom];
[self.doneButton addTarget:self action:@selector(doneButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
}
self.doneButton.adjustsImageWhenHighlighted = NO;
[self.doneButton setTitle:@"DONE" forState:UIControlStateNormal];
[self.doneButton.titleLabel setFont:[UIFont systemFontOfSize:16.0]];
[self.doneButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[self.doneButton setTitleColor:[UIColor blackColor] forState:UIControlStateHighlighted];
// locate keyboard view
if ([[[UIApplication sharedApplication] windows] count] <= 1) return;
UIWindow* tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
UIView* keyboard;
for(int i=0; i<[tempWindow.subviews count]; i++)
{
keyboard = [tempWindow.subviews objectAtIndex:i];
// keyboard found, add the button
if ([[keyboard description] hasPrefix:@"<UIPeripheralHost"] == YES)
{
BOOL isPortrait = UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation);
self.doneButton.frame = CGRectMake(((isPortrait)?0:-1),((int) (keyboard.frame.size.height*3)/4) + ((isPortrait)?0:1),(int) keyboard.frame.size.width/3-1, (isPortrait)?60:40);
[keyboard addSubview:self.doneButton];
}
//This code will work on iOS 8.0
else if([[keyboard description] hasPrefix:@"<UIInputSetContainerView"] == YES)
{
for(int i = 0 ; i < [keyboard.subviews count] ; i++)
{
UIView* hostkeyboard = [keyboard.subviews objectAtIndex:i];
if([[hostkeyboard description] hasPrefix:@"<UIInputSetHost"] == YES)
{
BOOL isPortrait = UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation);
self.doneButton.frame = CGRectMake(((isPortrait) ? 0 : -1),((int) (hostkeyboard.frame.size.height*3)/4) + ((isPortrait) ? 0 : 1),(int) hostkeyboard.frame.size.width/3-1, (isPortrait) ? 60 : 40);
[hostkeyboard addSubview:self.doneButton];
}
}
}
else{}
}
}
removeButtonFromKeyboard
- (void)removeButtonFromKeyboard
{
NSArray *arTemp = [[UIApplication sharedApplication] windows];
if ([arTemp count] <= 1) return;
UIWindow* tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
UIView* keyboard;
for(int i=0; i<[tempWindow.subviews count]; i++)
{
keyboard = [tempWindow.subviews objectAtIndex:i];
// keyboard found, add the button
if ([[keyboard description] hasPrefix:@"<UIPeripheralHost"] == YES)
{
for (id temp in keyboard.subviews)
{
if ([temp isKindOfClass:[UIButton class]])
{
UIButton *btnDone = (UIButton*) temp;
[btnDone removeFromSuperview];
break;
}
}
}
//This code will work on iOS 8.0
else if([[keyboard description] hasPrefix:@"<UIInputSetContainerView"] == YES)
{
for(int i = 0 ; i < [keyboard.subviews count] ; i++)
{
UIView* hostkeyboard = [keyboard.subviews objectAtIndex:i];
if([[hostkeyboard description] hasPrefix:@"<UIInputSetHost"] == YES)
{
for (id temp in hostkeyboard.subviews)
{
if ([temp isKindOfClass:[UIButton class]])
{
UIButton *btnDone = (UIButton*) temp;
[btnDone removeFromSuperview];
break;
}
}
}
}
}
else{}
}
}
Let me know any issues.
Update: Testing on iOS 7.1, real device - the button is not being added unless the keyboard show animation has finished. The code below adds a delay to add button once the keyboard is fully visible:
-(void)textFieldDidBeginEditing:(UITextField *)textField
{
[self performSelector:@selector(addButtonToKeyboard) withObject:nil afterDelay:0.75];
}
Okay here's a simple fix for getting 'done' button to show and work in my app in both iOS 9, iOS 8 and below when I got similar error. It could be observed after running an app and viewing it via 'View's Hierarchy' (i.e. clicking on the 'View Hierarchy' icon from Debug Area bar while app is running on device and inspecting your views in Storyboard), that the keyboard is presented on different windows in iOS 9 compared to iOS 8 and below versions and have to be accounted for. addButtonToKeyboard
- (id)addButtonToKeyboard
{
if (!doneButton)
{
// create custom button
UIButton * doneButton = [UIButton buttonWithType:UIButtonTypeCustom];
doneButton.frame = CGRectMake(-2, 163, 106, 53);
doneButton.adjustsImageWhenHighlighted = NO;
[doneButton setImage:[UIImage imageNamed:@"DoneUp.png"] forState:UIControlStateNormal];
[doneButton setImage:[UIImage imageNamed:@"DoneDown.png"] forState:UIControlStateHighlighted];
[doneButton addTarget:self action:@selector(saveNewLead:) forControlEvents:UIControlEventTouchUpInside];
}
NSArray *windows = [[UIApplication sharedApplication] windows];
//Check to see if running below iOS 9,then return the second window which bears the keyboard
if ([[[UIDevice currentDevice] systemVersion] floatValue] < 9.0) {
return windows[windows.count - 2];
}
else {
UIWindow* keyboardWithDoneButtonWindow = [ windows lastObject];
return keyboardWithDoneButtonWindow;
}
}
And this is how you could removeKeyboardButton from keyboard if you want.
- (void)removeKeyboardButton {
id windowTemp = [self addButtonToKeyboard];
if (windowTemp) {
for (UIView *doneButton in [windowTemp subviews]) {
if ([doneButton isKindOfClass:[UIButton class]]) {
[doneButton setHidden:TRUE];
}
}
}
}
If you using UITextfieldsDelegeates methods, you can simply call the addButtonToKeyboard method in the textFieldDidBeginEditing delegate method and that should do it. Now if you toggling back and forth between NumberPad and Default keyboard, it is recommended you call the removeKeyboardButton in "textFieldShouldEndEditing" delegate method to prevent any mishaps.
I did like "Alex-stone" but I can't to click custom button.
My solution:
//create DoneCustomReturnKeyButton to add into keyboard
- (void)addDoneCustomReturnKeyButtonInKeyboard:(NSNotification *)notification
{
NSArray *arr = [[[[UIApplication sharedApplication] windows] lastObject] subviews];
if (arr.count > 0) {
UIView *keyboardView = [arr objectAtIndex:0];
float height;
if ([[keyboardView description] hasPrefix:@"<UIPeripheralHost"] == YES) {
height = (CGRectGetHeight(keyboardView.frame) -
CGRectGetHeight(self.navigationController.navigationBar.frame)) / 4;
[self.doneCustomReturnKeyButton setFrame:CGRectMake(0, keyboardView.frame.size.height - height,
keyboardView.frame.size.width/3 - 2, height)];
[keyboardView addSubview:self.doneCustomReturnKeyButton];
}
//This code will work on iOS 8.0
else if([[keyboardView description] hasPrefix:@"<UIInputSetContainerView"] == YES)
{
for(int i = 0 ; i < [keyboardView.subviews count] ; i++)
{
UIView* hostkeyboard = [keyboardView.subviews objectAtIndex:i];
if([[hostkeyboard description] hasPrefix:@"<UIInputSetHost"] == YES)
{
UIButton* donebtn = (UIButton*)[hostkeyboard viewWithTag:67123];
if (donebtn == nil)
{
height = (CGRectGetHeight(hostkeyboard.frame) -
CGRectGetHeight(self.navigationController.navigationBar.frame)) / 4;
[self.doneCustomReturnKeyButton setFrame:CGRectMake(0, keyboardView.frame.size.height - height,
keyboardView.frame.size.width/3 - 2, height)];
[keyboardView addSubview:self.doneCustomReturnKeyButton];
}
}
}
}
}
else {
self.doneCustomReturnKeyButton.hidden = YES;
}
}
and create button.
- (void)createDoneCustomReturnKeyButton
{
self.doneCustomReturnKeyButton = [UIButton buttonWithType:UIButtonTypeSystem];
[self.doneCustomReturnKeyButton setTitle:NSLocalizedString(@"NEXT", nil) forState:UIControlStateNormal];
[self.doneCustomReturnKeyButton.titleLabel setFont:[UIFont systemFontOfSize:20]];
self.doneCustomReturnKeyButton.adjustsImageWhenHighlighted = NO;
self.doneCustomReturnKeyButton.backgroundColor = [UIColor lightGrayColor];
[self.doneCustomReturnKeyButton setTintColor:[UIColor whiteColor]];
[self.doneCustomReturnKeyButton addTarget:self
action:@selector(doneCustomReturnKeyButtonAction:)
forControlEvents:UIControlEventTouchUpInside];
}