iOS get Keyboard Window
10,284
Solution 1
I also had this problem and found the solution.
Below is the code which will work for iOS 8.0 and also for below versions.
I have tested it on iOS 7 and 8.0 (Xcode Version 6.0.1)
- (void)addButtonToKeyboard
{
// create custom button
self.doneButton = [UIButton buttonWithType:UIButtonTypeCustom];
self.doneButton.frame = CGRectMake(0, 163+44, 106, 53);
self.doneButton.adjustsImageWhenHighlighted = NO;
[self.doneButton setTag:67123];
[self.doneButton setImage:[UIImage imageNamed:@"doneup1.png"] forState:UIControlStateNormal];
[self.doneButton setImage:[UIImage imageNamed:@"donedown1.png"] forState:UIControlStateHighlighted];
[self.doneButton addTarget:self action:@selector(doneButton:) forControlEvents:UIControlEventTouchUpInside];
// locate keyboard view
int windowCount = [[[UIApplication sharedApplication] windows] count];
if (windowCount < 2) {
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){
UIButton* searchbtn = (UIButton*)[keyboard viewWithTag:67123];
if (searchbtn == nil)//to avoid adding again and again as per my requirement (previous and next button on keyboard)
[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){
UIButton* donebtn = (UIButton*)[hostkeyboard viewWithTag:67123];
if (donebtn == nil)//to avoid adding again and again as per my requirement (previous and next button on keyboard)
[hostkeyboard addSubview:self.doneButton];
}
}
}
}
}
>
-(void) removedSearchButtonFromKeypad{
int windowCount = [[[UIApplication sharedApplication] windows] count];
if (windowCount < 2) {
return;
}
UIWindow* tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
for(int i = 0 ; i < [tempWindow.subviews count] ; i++)
{
UIView* keyboard = [tempWindow.subviews objectAtIndex:i];
if([[keyboard description] hasPrefix:@"<UIPeripheralHost"] == YES){
[self removeButton:keyboard];
}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){
[self removeButton:hostkeyboard];
}
}
}
}
}
-(void) removeButton:(UIView*)keypadView{
UIButton* donebtn = (UIButton*)[keypadView viewWithTag:67123];
if(donebtn){
[donebtn removeFromSuperview];
donebtn = nil;
}
}
Hope this helps.
Solution 2
What i use to get the window for the keyboard is
- (void)findKeyboardWindow
{
for (UIWindow *window in [[UIApplication sharedApplication] windows])
{
if ([NSStringFromClass([window class]) isEqualToString:@"UITextEffectsWindow"])
{
_keyboardWindow = window;
break;
}
}
}
From my logs on iOS8 this contains one view
UIInputSetContainerView: 0x190d4430; frame = (0 0; 320 568); autoresize = W+H; layer = CALayer: 0x190d4630
Which contains another view
UIInputSetHostView: 0x190d4820; frame = (0 352; 320 216); layer = CALayer: 0x190d49c0
Since those dimensions are 216.0f height i guess that is the keyboard. Was this what you where looking for?
Solution 3
On iOS 13, we can get keyboard window like this:
let windows = UIApplication.shared.windows
if let keyboardWindow = windows.first(where: { NSStringFromClass($0.classForCoder) == "UIRemoteKeyboardWindow" }) {
return
}
Author by
SaifDeen
Updated on June 05, 2022Comments
-
SaifDeen almost 2 years
So in iOS 7 I always got the Keyboard Window like this:
- (UIView *)keyboardView { UIWindow* tempWindow; //Because we cant get access to the UIKeyboard throught the SDK we will just use UIView. //UIKeyboard is a subclass of UIView anyways UIView* keyboard; NSLog(@"windows %d", [[[UIApplication sharedApplication]windows]count]); //Check each window in our application for(int c = 0; c < [[[UIApplication sharedApplication] windows] count]; c ++) { //Get a reference of the current window tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:c]; //Get a reference of the current view for(int i = 0; i < [tempWindow.subviews count]; i++) { keyboard = [tempWindow.subviews objectAtIndex:i]; NSLog(@"view: %@, on index: %d, class: %@", [keyboard description], i, [[tempWindow.subviews objectAtIndex:i] class]); if([[keyboard description] hasPrefix:@"(lessThen)UIKeyboard"] == YES) { //If we get to this point, then our UIView "keyboard" is referencing our keyboard. return keyboard; } } for(UIView* potentialKeyboard in tempWindow.subviews) // if the real keyboard-view is found, remember it. if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) { if([[potentialKeyboard description] hasPrefix:@"<UILayoutContainerView"] == YES) keyboard = potentialKeyboard; } else if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 3.2) { if([[potentialKeyboard description] hasPrefix:@"<UIPeripheralHost"] == YES) keyboard = potentialKeyboard; } else { if([[potentialKeyboard description] hasPrefix:@"<UIKeyboard"] == YES) keyboard = potentialKeyboard; } } NSLog(@"view: %@, on index: %d", [keyboard description]); return keyboard; }
But in the iOS 8 beta 1 & 2 the window/view that is returned is the main App window. Any idea what is the the problem in my code? On my test device with iOS 7 it works great...
-
gregthegeek over 9 yearsPure awesomeness! You saved me lots of extra hassle. And what's more... Our original code must have been from same boilerplate example, because this almost dropped right in place. Nice! Thanks!
-
iAnurag over 9 yearsI have used the same code for adding done button, it worked for me, but when default keyboard appeares I can see that done button behind the keyboard even If I have removed it from superview. plz help. Thanks
-
Manjit Singh over 9 yearsplease tell me how to remove the done button and predictive text bar from the keyboard.
-
iGW over 9 yearsI have edited my code which supports removing done button from the keyboard. Please have a look on the complete code.
-
Manjit Singh over 9 yearsplease see this question am doing same like this stackoverflow.com/questions/26213708/…
-
iGW over 9 yearsI have not yet upload the app to the app store with this code. Have you found any restriction?
-
Gustavo Barbosa over 9 yearsThis is the best solution!
-
Developer almost 9 yearsYes! I am able to add the button but not able to interact with that. I can see only image which I placed on the keyboard.