Getting a password on the fly is one of those times.
This snippet was put together as a utility function, independent of class, implementation and delegate methods. Feel free to use it and adapt it as you see fit, and it would be nice if you'd toss a line of credit in there somewhere.
NSString * DisplayModalPasswordEntry (NSString *szTitle, NSString *szMessage)
{
// First, initialize the alert with our desired title and message
// The delegate is nil because we will not be allowing delegate methods
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:szTitle
message:szMessage
delegate:nil
cancelButtonTitle:@"Cancel"
otherButtonTitles:@"OK",
nil];
// Make the entry secure
[alert setAlertViewStyle:UIAlertViewStyleSecureTextInput];
// Show our alert
[alert show];
// NSRunLoop will handle our blocking without explicitly blocking
// NSDate will provide us with a condition for the NSRunLoop
// UITextField and UIButton are for editing purposes during the loop
NSRunLoop *rl = [NSRunLoop currentRunLoop];
NSDate *d;
UITextField *pTextField = [alert textFieldAtIndex:0];
UIButton *pOKButton;
// This loop goes through the subviews in alert looking for our button
for (UIView *view in alert.subviews)
{
// If it's a button
if([view isKindOfClass:[UIButton class]])
// And if it's the button we're looking for
if ([((UIButton *)view).titleLabel.text isEqualToString:@"OK"])
{
pOKButton = (UIButton *)view;
break;
}
}
// So long as the alert is active
while ([alert isVisible])
{
// NSDate init returns 'now'
d = [[NSDate alloc] init];
// runUntil will run once and stop, since 'now' is 'then
[rl runUntilDate:d];
// Since we've disallowed delegate methods, we handle our button status here
if ([pTextField.text length] == 0)
pOKButton.enabled = NO;
else
pOKButton.enabled = YES;
}
// Once we break out of our loop, we return whatever they entered
return pTextField.text;
}