Displaying a password or text entry prompt on the iPhone

Writing your own iPhone or iPod touch app, and wondering how to create an alert like this? Check out the sample code below.

I needed to display a password prompt in Delivery Status touch and quickly found that there was no ideal way to do it. There are some unsupported methods, but the workaround below—adding a UITextField as a subview of the alert—is the proper method for a third party app, according to Apple.

Aside from the basic technique of adding a UITextField as a subview, there are two other things I struggled with. First, if the text given for the message was too long it would wrap to a second line and appear partially underneath the text field. I worked around this problem by adding my own UILabel subview. The custom label is a single line so you’ll get the standard ellipsis (…) if the text is too long. For the message text I just supply three blank lines, which makes the alert large enough to display the contents. It’s a clunky way to resize the alert, but it works.

The other thing I struggled with was getting the text field to match what Apple uses. The standard beveled edge looks okay, but Apple’s own password prompts have a field that’s customized specifically for alerts. My solution was to insert an image, and display the text field, without a border, on top of it. Here’s the image I’m using.

Using those tricks, here’s the complete code I’m using to display a password prompt:

UIAlertView *passwordAlert = [[UIAlertView alloc] initWithTitle:@"Server Password" message:@"\n\n\n" delegate:self cancelButtonTitle:NSLocalizedString(@"Cancel",nil) otherButtonTitles:NSLocalizedString(@"OK",nil), nil]; UILabel *passwordLabel = [[UILabel alloc] initWithFrame:CGRectMake(12,40,260,25)]; passwordLabel.font = [UIFont systemFontOfSize:16]; passwordLabel.textColor = [UIColor whiteColor]; passwordLabel.backgroundColor = [UIColor clearColor]; passwordLabel.shadowColor = [UIColor blackColor]; passwordLabel.shadowOffset = CGSizeMake(0,-1); passwordLabel.textAlignment = UITextAlignmentCenter; passwordLabel.text = @"Account Name"; [passwordAlert addSubview:passwordLabel]; UIImageView *passwordImage = [[UIImageView alloc] initWithImage:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"passwordfield" ofType:@"png"]]]; passwordImage.frame = CGRectMake(11,79,262,31); [passwordAlert addSubview:passwordImage]; UITextField *passwordField = [[UITextField alloc] initWithFrame:CGRectMake(16,83,252,25)]; passwordField.font = [UIFont systemFontOfSize:18]; passwordField.backgroundColor = [UIColor whiteColor]; passwordField.secureTextEntry = YES; passwordField.keyboardAppearance = UIKeyboardAppearanceAlert; passwordField.delegate = self; [passwordField becomeFirstResponder]; [passwordAlert addSubview:passwordField]; [passwordAlert setTransform:CGAffineTransformMakeTranslation(0,109)]; [passwordAlert show]; [passwordAlert release]; [passwordField release]; [passwordImage release]; [passwordLabel release];

You can see the result of this code in the screenshot above. It can be customized fairly easily, if you need another type of text entry, more lines of text, or some other change. (Remove the secureTextEntry line or change the keyboardAppearance to customize the text entry field.)

I spent quite a bit of time getting it as pixel-perfect as possible. The only real difference is that it’s a few pixels taller than Apple’s, because of the imprecise way I’m sizing the alert. I think it’s fair to say most people would never notice! I’d love to see a more simplified, official method for creating these alerts, but in the meantime I’m pretty pleased with this solution. If you have any suggestions for improvements, let me know in the comments!

Update: Chris Garman sent me an email to let me know there’s a simpler way to get a good looking text entry field:

Remove the image, and the font and backgroundColor assignments.
Add passwordField.borderStyle = UITextBorderStyleRoundedRect;

This won’t look exactly the same as the dialogs that Apple uses, but it is a nice looking, simpler alternative!

Comments

This entry has 8 comments.

Adam Ernst

Adam Ernst wrote on November 24, 2008:

Genius! Thanks for sharing this. This will save a lot of developers plenty of time. :-)

Devon

Devon wrote on December 3, 2008:

Great job! You created a very elegant imitation.

BCH

BCH wrote on December 17, 2008:

How do you get a hold of the text entered though? I have done something similar, but haven’t been able to access the text the user entered.

Mike Piontek

Mike Piontek wrote on December 18, 2008:

To get the text entered you just need to set a delegate for the text field and the alert, as shown in the example code above. Then you can use textFieldDidEndEditing: to get the value and store it somewhere temporary. When alertView:didDismissWithButtonIndex: is called, you can look up the saved value, and either use it or discard it depending on what button was pressed.

bbar

bbar wrote on January 13, 2009:

I’ve seen other apps do this before, like Navizon, which has been out for a while. What do you mean when you say it’s the correct way to do it ‘according to Apple’? Is it in there documentation somewhere? If so, where? Thanks.

Mike Piontek

Mike Piontek wrote on January 14, 2009:

A poster on Apple’s iPhone developer message boards asked how to accomplish this. Someone from Apple said that currently, the recommended method is to add subviews to a UIAlertView. This example is based on that recommendation.

It’s my understanding that there’s another way to do this using undocumented APIs. Needless to say Apple doesn’t want people doing that.

All of the methods used in this example are documented. Apple does not provide any specific documentation or examples on how to create this type of text entry prompt, which is why I put together this example.

Victor

Victor wrote on February 25, 2009:

Hi,

This was really very helpful. Thank you very much for sharing this.

Isaac Waller

Isaac Waller wrote on March 7, 2009:

Thanks - really saved me tons of time!

View more

Code

VoiceOver tips for iPhone developers I’ve been working on improving VoiceOver support for Delivery Status touch 3.0. It was…

My First WWDC Above: Apple’s live App Store wall at WWDC. It showed icons of 20,000 iPhone apps,…

Junecloud: coming soon

Tense Log 2.1 beta 2 now available! (Updated) Above: the Tense Log crop tool, a new feature in version 2.1 This is a pretty big…