7

[EDIT] Hmm. Perhaps this question should be titled "what is the default user-input dialog view called in CocoaTouch?" I realize that I can create an entire view that is exactly what I want, and wrap it in a view controller and presentModalView -- but I was sort of hoping that there was a standard, normal user-input "dialog" view that came-with Cocoa-touch. "Enter your name", "enter text to search", etc., are VERY common things!

Anyway... here's the question as I originally asked it:

This code:

UIAlertView* find = [[UIAlertView alloc] init];
[find setDelegate:self];
[find setTitle:@"Find"];

[find addButtonWithTitle:@"Cancel"];
[find addButtonWithTitle:@"Find & Bring"];
[find addButtonWithTitle:@"Find & Go"];
[find addButtonWithTitle:@"Go To Next"];

[find addSubview:_findText];

CGRect frm = find.frame;
int height = frm.size.height + _findText.frame.size.height + 100; // note how even 100 has no effect.
[find setFrame:CGRectMake(frm.origin.x, frm.origin.y, frm.size.width, height)];

[find setNeedsLayout];
[find show];
[find release];

Produces this Alert view:

Find Alert http://www.publicplayground.com/IMGs/Misc/FindAlert.png

(I started with the code from this question by emi1Faber, and it works as advertised; however, as I state in my comment, the cancel button overlays the text field.)

How do I reshuffle everything to make the text field fit properly? [findAlert setNeedsLayout] doesn't seem to do anything, even after I [findAlert setFrame:tallerFrame]. Hints?

Thanks!

Community
  • 1
  • 1
Olie
  • 24,597
  • 18
  • 99
  • 131

8 Answers8

25

The simplest (and most proper way) to move the text view down is to add a message

[find setMessage:@"\n"];

Also, the reason your frame isn't taking effect is that -show sets the frame and creates the view hierarchy before starting the animation. You should also make the text view the first responder so the keyboard pops up.

Full example:

// Create Alert
UIAlertView* av = [UIAlertView new];
av.title = @"Find";
// Add Buttons
[av addButtonWithTitle:@"Cancel"];
[av addButtonWithTitle:@"Find & Bring"];
[av addButtonWithTitle:@"Find & Go"];
[av addButtonWithTitle:@"Go to Next"];
// Make Space for Text View
av.message = @"\n";
// Have Alert View create its view heirarchy, set its frame and begin bounce animation
[av show];
// Adjust the frame
CGRect frame = av.frame;
frame.origin.y -= 100.0f;
av.frame = frame;
// Add Text Field
UITextField* text = [[UITextField alloc] initWithFrame:CGRectMake(20.0, 45.0, 245.0, 25.0)];
text.borderStyle = UITextBorderStyleRoundedRect;
[av addSubview:text];
[text becomeFirstResponder];

Note: You can also modify the subviews of UIAlertView, but since Apple has already changed the UIAlertView layout once you should check their class descriptions and frames against known values before setting new ones. You can even get something like this:

Preview
(source: booleanmagic.com)

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
rpetrich
  • 32,196
  • 6
  • 66
  • 89
  • Yes. [find setmessage:@"\n"] is the call for which I was looking. Still investigating approved dailogs, but I believe this is it. Thanks! – Olie Jan 12 '09 at 21:03
  • 6
    @repetrich how did you insert 4 buttons in two columns are they custom buttons or is there some trick hidden please throw some light on this. – Madhup Singh Yadav Dec 21 '09 at 09:54
  • dear rpetrich in your screenshot u have shown four buttons in two columns. how u achieved that ?? provide code example will be extra help – luckee Dec 07 '09 at 12:08
6

Even if you can get this working it's not going to be very iPhone-y. The UIAlertView really is not designed for user input like this. If you look in all the Apple apps you'll see that they use a new view that displayed using the presentModalViewController: method of UIViewController.

Edit: This advice is no longer as true as it was when I wrote it. Apple have increasingly used alert views as text entry boxes and iOS5 even includes native support without having to mess around with views (check out the alertViewStyle property).

I think maybe if you need to have four buttons then using a custom UIViewController is probably still the right way to go. But if you just want to enter a password with OK/Cancel buttons then it's fine.

Stephen Darlington
  • 51,577
  • 12
  • 107
  • 152
  • Ahhhh, I'll check into that. Of course, I prefer a "proper UI" solution, I just couldn't find it under "dialog" or my other searches. Thanks! – Olie Jan 03 '09 at 20:00
  • Btw, how did you get the buttons to layout 2x2? Did you subclass, or is this all done with an off-the-shelf UIAlert? Thanks! – Olie Jan 16 '09 at 21:56
3

Zoul proposed the best method, to capture user input just do:

a) Add the UITextFieldDelegate protocol to your class.

b) Do something like

    UIAlertView *insertScore = [UIAlertView new];
    [insertScore setDelegate:self];
    [insertScore setTitle:@"New Title!"];
    [insertScore addButtonWithTitle:@"Cancel"];
    [insertScore addButtonWithTitle:@"Ok"];

    insertScore.message = @"\n";

    [insertScore addTextFieldWithValue:@"Input" label:@"player"];

    [[insertScore textField] setDelegate:self];

    [insertScore show]; 

    [insertScore release];

c) The crucial part was to set the delegate of the textField to self, then to access data you can simply:

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex 
{
  NSLog(@"%@",[[alertView textField] text]);
}

Hope this helps someone, since I had to think a bit to get it right.

sth
  • 222,467
  • 53
  • 283
  • 367
Goles
  • 11,599
  • 22
  • 79
  • 140
1

Explains how to set the number of columns, have not tested it.

http://iloveco.de/uikit-alert-types/

However there is a private method, setNumberOfRows:(int)n that will allow you to set a maximum number of rows to display the buttons in. To use this method we need to add our own additions to the UIAlertView class. We do this by adding an @interface for UIAlertView in our .m file.

// extend the UIAlertView class to remove the warning caused
// by calling setNumberOfRows.
@interface UIAlertView (extended)
- (void) setNumberOfRows:(int)num;
@end

This will allow us to call the method without the compiler throwing us a warning.

[myAlert setNumberOfRows:2];
oden
  • 3,461
  • 1
  • 31
  • 33
1

Most probably You would want to look into the addTextFieldWithValue method of the UIAlertView? Add the following code somewhere at the top of Your class:

@interface UIAlertView ()
- (void) addTextFieldWithValue: (NSString*) val label: (NSString*) label;
- (UITextField*) textField;
@end

It’s not official, but IMHO it’s not getting You rejected from the App store and it’s much better solution than hacking the textfield into the dialog Yourself.

zoul
  • 102,279
  • 44
  • 260
  • 354
  • 1
    This may not have been the case back then, but I've recently read about several rejections on the grounds of using this private API call. Apple has a new solution in place that is checking for any private API usage and really cracking down hard on this practice. – Mirko Froehlich Nov 24 '09 at 23:07
  • Yep, I just got rejected for this very reason. – zpasternack Aug 24 '10 at 06:05
0

Try putting in some (\n)s after the title in the UIAlertView initialization. That will push down the buttons. And I agree with Stephen here. There are chances that Apple might reject an app if it uses controls in a way they shouldn't be. (there's some clause in the Human Interface Guidelines about that!)

lostInTransit
  • 70,519
  • 61
  • 198
  • 274
0

This simpler method works for me:

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"UIAlertView"
    message:@"<Alert message>" delegate:self cancelButtonTitle:@"OK"
    otherButtonTitles:nil];
[alert addTextFieldWithValue:@"" label:@"Text Field"];

Hope that helps. Oh if you needed multiple button rows then it's:

[alert setNumberOfRows:3];

Cheers

zoul
  • 102,279
  • 44
  • 260
  • 354
Megachan
  • 9
  • 1
0

https://github.com/TomSwift/TSAlertView

This library actually creates the control from scratch rather than attempting to hack UIAlertView, which is generally a Bad Plan (TM)

P i
  • 29,020
  • 36
  • 159
  • 267