tags:

views:

3647

answers:

3

I'm new to the iPhone and I would like to be able to use UIAlertView in a manner similar to the Windows MessageBox() or the MessageDlg() in Delphi.

For example, I have a method that needs to ask the user for confirmation on something, and proceed based on their response.

E.g. (pseudocode):

-(void)doSomething
{
  [doStep1];
  [doStep2];
  var myValue = [getDefaultValue];

  if (myValue = nil)
  {
    if [promptUser(@"No value in setting. Use the default value?")] //UIAlertView here?
    {
       myValue = @"defaultValue";
    }
    else
      return;  // bug out of the routine 'cause we have no value.
  }

  [doStep3 withValue:myValue];

}

Or, put put it another way- is there a way of using UIAlertView to ask the user a question within a routine as a way of controlling the logic flow of that routine?

+2  A: 

I have no idea what MessageDlg() is, but you can certainly subclass UIAlertView and handle the dialog response, based on which button is pressed, e.g.:

Set up the UIAlertView subclass header:

//
//  ARReachabilityAlertView.h
//

#import <UIKit/UIKit.h>

@interface ARReachabilityAlertView : UIAlertView <UIAlertViewDelegate> {
}

@end

Set up the UIAlertView subclass implementation:

//
//  ARReachabilityAlertView.m
//

#import "ARReachabilityAlertView.h"

@implementation ARReachabilityAlertView

- (id)initWithFrame:(CGRect)frame {
  if (self = [super initWithFrame:frame]) {
    [self setTitle:@"Error"];
    [self setMessage:@"This application won't run without a network connection. Do you want to quit?"];
    [self addButtonWithTitle:@"Quit"];
    [self addButtonWithTitle:@"Continue"];
    [self setDelegate:self];
  }
  return self;
}

- (void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
  if (buttonIndex == 0)
    exit(0); // quit application if "Quit" is pressed; otherwise, do nothing
}

- (void) drawRect:(CGRect)rect {
  [super drawRect:rect];
}

- (void) dealloc {
  [super dealloc];
}

@end

Note the alertView:clickedButtonAtIndex: delegate method. This handles the conditionals you use to decide how the application proceeds. You can send an NSNotification from here, or call a method in the application delegate, whatever you want.

In my example, this UIAlertView is instantiated if there is no network connection, and the application is closed if the user clicks "Quit" in the alert view. Otherwise, if the user clicks "Continue" the application keeps running as usual.

Note that the implementation of the subclass requires the drawRect: method be called. I'm not sure if this is a bug or not, since I'd expect the drawRect: method to be called in the super-class; I filed a bug report with Apple on this one, but I haven't heard anything. Comment it out if you want to see what the effect will be — it's kind of interesting.

Alex Reynolds
Just came across this question - note you can just set some other class as a delegate of the alert view, there's no need to ever subclass UIAlertView!!
Kendall Helmstetter Gelner
+2  A: 

I believe you're looking to use UIAlertView as a modal alert box (in the sense that you'd like your code to stop running until the user makes a selection). There's no easy way to do this, and it's really recommended that you NOT code for the iPhone in this manner. I think Alex's explanation is a good solution.

Ben Gottlieb
+4  A: 

There's no reason to subclass UIAlertView at all. That's what delegates are for. All you need is a class (such as your view controller) supporting the UIAlertViewDelegate protocol, and set the UIAlertView's delegate property to that class. You then implement the alertView:clickedButtonAtIndex: method in this class, and the alertViewCancel: method if you want to specifically handle cancellations differently.

You can read more about it in the UIAlertView documentation and in the UIAlertViewDelegate documentation.

HitScan
What if you want your application to call more than one type of alert view? It's harder (i.e. will be difficult to debug) to set up the delegate method required to differentiate between different UIAlertView instances, and set up the different logic required for those different UIAlertViews. Subclassing takes a lot of the work out of this.
Alex Reynolds
You can just make classes that do nothing but implement the UIAlertView protocol. Notice above that in the example code for the subclassed example he's still using that protocol, and setting the delegate to self. The only subclassing thing done was to implement [super (method)] calls where required.
HitScan
I forgot to point out in that comment that you can have multiple classes that only implement the UIAlertViewDelegate protocol, and that way it's easy to handle multiple UIAlertViews.
HitScan