****** IMPORTANT*******
Inside the code segements, some code i had was causing the code blocks to mess up and cut out code, so please not that when i write hasPrefix:@"(lessThen)UIKeyboard" the (lessThen) should be replaced by the actual symbol. so like this hasPrefix:@"***********************
*******************************************************
* There is a code example a few posts down that has all this code in it *
*******************************************************
This tutorial will show an example of how to add content to a UIKeyboard by adding a custom button. The following will show you how to add a decimal button to the numeric keyboard so you can enter decimal values without having to use a full keyboard. The key idea to understand here is that although the UIKeyboard is not directly available to us through the current iPhone SDK, we can still reference an instance of the keyboard using its base class.
UIKeyboard is a subclass of UIView. This is handy because it is very easy to add content to a view using code like below:
[myView addSubview:subview];
This is how we will add a button to our keyboard, by referencing the keyboard and adding a subview.
In my program I only had one keyboard and on text area to use the keyboard, so the following code worked fine for me. This example is not robust enough to handle multiple keyboard and multiple text areas but hopefully it gives you a good idea how things work.
STEP 1: Finding the UIKeyboard
The first thing we have to do is actually get a reference to the UIKeyboard. If your application uses a keyboard, you will find that they keyboard is not actually inside the UIWindow you create in your applicationDelegate, but in a separate UIWindow that is automatically generated. Each iPhone application you create has an array of windows. The example below shows you how to reference an item in your applications array of UIWindows.
UIWindow* tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
The code above works fine if you know what window you want to reference. I am not 100% sure what the max number of windows an application can have is, but in general it is better to write smart code that can automatically find each window, instead of writing working code once and hoping that conditions never change. With that said lets take a look at the following code example. The code blow shows how to iterate through each window in our applications
UIWindow* tempWindow;
//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];
}
So now that we are able to loop through all of our application windows, we are ready to starting looking for the UIKeyboard. As mentioned before, UIKeyboard is a subclass of UIView. This is helpful because each UIWindow has an array of its subviews. All we have to do now is loop through each subview of the current window. We can do this with a nested for loop. Below is an extended version of the code above that will show you how to iterate through all the subviews in a window.
UIWindow* tempWindow;
//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++)
{
}
}
Now we are at the point where we can look for the view that contains the keyboard. There are a couple of ways you can check the content/type of a UIView, in my code I do this by checking the prefix of the view description. Through debugging I found out that a UIKeyboard description starts with the text "
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;
//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];
if([[keyboard description] hasPrefix:@\"(lessThen)UIKeyboard\"] == YES)
{
//If we get to this point, then our UIView \"keyboard\" is referencing our keyboard.
}
}
}
So there you have it. Using a couple simple loops, we can reference our keyboard. Next, we need to add content.
STEP 2: Adding a custom button to the keyboard.
So now that we have a UIView reference of the keyboard. Adding a custom button is actually really simple. All we need to do is add a subview to the keyboard view. Below is the code that I use in my application to add a peroid to my numeric keypad keyboard. Keep in mind that we are referencing the keyboard directly, so position 0, 0 is not the top left of your screen, rather the top left of the keyboard. Remeber that the variable keyboard is the UIView we found in step1.
dot = [UIButton buttonWithType:UIButtonTypeCustom];
dot.frame = CGRectMake(0, 163, 106, 53);
[dot setImage:[UIImage imageNamed:@\"period.gif\"] forState:UIControlStateNormal];
[dot setImage:[UIImage imageNamed:@\"period2.gif\"] forState:UIControlStateHighlighted];
[keyboard addSubview:dot];
[dot addTarget:self action:@selector(addDot:) forControlEvents:UIControlEventTouchUpInside];
The code is just as simple as adding any other button. The button has 2 images, one for when its not clicked and one for when it is. When the button is pressed I want to update my textbox by appending a '.' which is show in the code below.
gameOptions.size.text = [gameOptions.size.text stringByAppendingString:@\".\"];
Now this was a little bit more difficult in my case then what I showed, that is because where I add the button, and where the buttons textarea target are in 2 different classes. But there are plenty of examples of calling methods from other classes on these forums so i wont get into that. If I can figure out how I will include the 2 images I used for this button in this tutorial so that anyone who wants to use them can.
STEP 3: Where does all this code go?
So here comes the point where I tell you that I am not 100% sure that what I am about to write is the best way to do things. There are most likely better places to add buttons to your text boxes, I just did it the following way. It will work fine, but you are more then welcome/encouraged to find a better solution.
Using notifications we can easily find out when a keyboard is about to be shown and attach a method to that event. Because a keyboard cannot be show without this method being called, I figured it would be a good place to reference the keyboard. This way we dont waste any time creating a custom keyboard if the user never uses a textarea.
I put all this code into the app delegate. I figured it was a good spot because it will live as long as my application does. Below is the first thing you need to do. As mention before, I wanted to listen for the notification of when the keyboard will be shown. The following line of code shows how to do this.
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
As seen above, i just told my application that each time the keyboard is shown, I want to call the method keyboardWillShow. This method is where all the code from step 1 and 2 is held. As mentioned this method sits inside of my app delegate. The follow code is what my appDelegate looks like. As you can see I have a function keyboardWillShow that handles events due the the code above. Each time the keyboard is to be shown we will add our button. The way i have done things, if you do not do this each time, the button will not persist. I hope this all makes sense.
--- My post is to long, tutorial continues below ---
Replies
If you have any questions let me know. This is probably the only tutorial I have ever written so I understand if it was confusing. Ive also included a screen shot of the keyboard and the images for the buttons you can use to add a decimal.
Good Luck :)
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeAny chance you could post an example project with this code?
Thanks
Greg
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like Awesome- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeFYI: I posted a related thread here:
https://devforums.apple.com/message/18403
In case you are interested or want to post your thoughts.
Thanks
Greg
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeAttached is a quick little example project I made as per the request above.
I also included some code that moves the screen up and down as the keyboard is shown so that the textfield is never hidden.
The code is pretty much the same as the tutorial so its not super commented cause i wrote it quickly right now.
Let me know if there are any problems
Thanks
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeMake sure that you import the AudioToolBox framework!
And copy the sound file to your project.
The textField has to be of the type "NumberPad". Otherwise it will look weird.
This will also work with multiple textFields. ;)
FKTextField.h:
FKTextField.m:
It's not that much but I hope it will help someone. ;)
edit:
Something is messed up with the second code block.
Quote me or download the files. ;)
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like Awesome- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like Awesome- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeHere is my blog entry explaining my changes:
Billabonger.net » Blog Archive » Add a Decimal to UITextField : Number Pad Keyboard
And Here is the XCode Example Project:
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like Awesome- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeBut I have this Question.
Does any one has solved the cursor position problem?
What I mean is, suppose you write "1234567890" and then you press "." and everything goes perfect. But how about inserting "." somewhere else rather than the tail?
for example in order to write "1234567.89" you will have to delete 8 and 9 and then write "." and then write "89" again.
I know this is something it has to be with UIKeyboard, which 3rd party programmers are not allowed to play with. But maybe there is a good idea someone could have... Any thoughts?:D
In case of UITextView I think can calculate the actual position by a function of the tapped possition, and current font sizes. But I don't know how accurate this method can be. I case of UITextField I am not sure whether I can do it.
Any ideas?
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like Awesome- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeJust implement a UITextFieldDelegate and in particular the method:
The range corresponds to the current cursor position and the string corresponds to the pressed key. If you want to allow the keypress at the given cursor position, return YES. If you don't like it, just return NO. If you want to substitute something in place of the pressed key, use something like
and return NO.
Of course, since there's no publicly documented way to generate a "keypress" event then I guess you may still be stuck!
Oh wait, never mind... In just poking around, I see there's a handy method/property if you use a UITextView instead of a UITextField:
That may be helpful, if you can dress up the text view to look more like a text field, and add the clear button to it, and so forth.... I still don't understand why this method isn't available in a text field. It's obviously very handy.
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like Awesome- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeI used brygruver blog method, and I have it working except it only adds the decimal point to the same textfield. If you have an interface with 4 textfields (textfield1, texfield 2...texfield4). How do you say in the
- (void)addDecimal:(NSNotification *)notification Method to append the '.' to the selected textfield??
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeThanks!
Boxen4Oxen <a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=328074748&mt=8" target=
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like Awesomewww.CocoaLines.com - Custom Number Pad
- (void)textFieldDidBeginEditing:(UITextField *)textField {// We need to access the dot Button declared in the Delegate.
ExampleAppDelegate *appDelegate = (ExampleAppDelegate *)[[UIApplication sharedApplication] delegate];
// Only if we are editing within the Number Pad Text Field do we want the dot.
if (numericTextField.editing) {
// Show the Dot.
appDelegate.dot.hidden = NO;
} else {
// Otherwise, Hide the Dot.
appDelegate.dot.hidden = YES;
}
}
You could also do:
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeThank you everybody for this post.
I customized with success my keyboard.
I'm trying get the international keyboard that was selected when click the international key (globe icon).
Anybody can help me?
Patricia.
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeI have a custom keyboard (dial pad of buttons) and wanted to retain the copy/paste functionality. (keyboard.hidden=YES is my friend :) ).
What are the implications, if any, of getting it approved by Apple for the app store?
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeWe're talking about this now on the Apple developer forums - and one of the Apple employees seems to imply that this will result in a rejection.
Developers may wish to report a Bug in the Apple Bug Tracking system in order to elevate this issue and get an official resolution from Apple.
-t
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeWith that said hopefully the information on here has been helpful to some of you.
Cheers :)
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeFor the next version of my app I took a cue from FastWriter (Fast Writer Adds Extra Row of Keys to the iPhone’s Keyboard Art of the iPhone) and added an extra row of keys. I even went to the trouble of Photoshopping up the enlarged key thingies so I could make it look and act just like the regular keyboard.
Here are two handy methods that helped to get the proper behavior:
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomebugWar by MechDog
<a href="http://itunes.apple.com/us/app/mytip/id346952226?mt=8&uo=6\" target="_b
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeApparently we were warned not to do this in the SDK 3.0 release notes, and since this "trick" relies on an undocumented call to find the name of the keyboard (walking the subviews until we find the one with the name we think it should be) it's going to - if it doesn't already - flag the code checker somehow...
The Apple recommendation was to submit a bug report.
The only other recommendation - from non-Apple employees in the forum - was to create a completely new, custom keypad and handle all the necessary events yourself. Not a great solution.
My App was just submitted with the Decimal point added to the keypad using this trick - so I guess I'll see if it gets through the gauntlet or not.
I've begun work on a totally custom keypad as a backup plan, but it's going to take some time to get it right and fully functional I'm afraid.
-t
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like Awesome- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like Awesome