Modal Alert

Hello,

I'd like to display a simple message box (UIAlertView or whatever) in a modal manner, something like:

-(void) myfunc
{
display modalmessage(@"Some message");

do some_otherstuff();
}

I'd like to have the function do some_otherstuff() be called only when user dismisses the message box that gets displayed in the display modalmessage() function.

What is the correct way to do this in iPhone SDK?

Haven't been able to create an NSAlert in iPhone SDK, as #import <NSAlert.h> fails.
Haven't seen a way to create a modal UIAlertView either.

What are the options?

What is in general the way to display modal views to the user? (where modal means not only blocking background UI, but also blocking code execution in a local run loop or something --as in the example above).


Thanks.

Mac OS X (10.5.3), Mac Mini

Posted on Jun 8, 2008 4:38 AM

Reply
9 replies

Jun 8, 2008 8:57 AM in response to Chamcham

I haven't been able to find a truly modal solution to this issue.

However, the standard way to do stuff like this is to either use an UIAlertView or UIActionSheet. Both have delegate messages you can respond to for their button presses.

So if you always want the code to execute when the alert is dismissed, create the AlertView or ActionSheet with just an OK button, and respond to the delegate message that says a button was pressed, putting the code to execute in that delegate method.

You can also define OK and Cancel buttons, and execute the code only if the OK button is pressed.

Hope this helps,
Ron

Jun 8, 2008 4:00 PM in response to itripn

I have looked all over the docs and INet, but found nothing. 😟

Of course UIAlertView blocks any background UI input, so it actually forces the user to dismiss the alert, but your code is not modal, so that what a traditional modal window offers in simplicity of usage, on iPhone seems like a nightmare forcing you to use delegates all over the place, unless you come up with the solution I've found, however it may seem a bit odd, and dependant on future implementation changes on UIAlertView:

@implementation Util
+(void) runModal:(UIView *)view
{
view.hidden=FALSE;
while (!view.hidden && view.superview!=nil)
[[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01]];
}
+(void) Message:(NSString *)text
{
UIAlertView *alert=[[UIAlertView alloc] initWithTitle:@"My App" message:text delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
[Util runModal:alert];
}
@end


Now you'd just have to do an [Util Message:@"Hey I'm modal!"],and the message sent will not exit until user dismisses the message.

I don't know if this is all correct though; I'm completely new to iPhone SDK & Obj-C.

Jun 8, 2008 8:38 PM in response to Chamcham

No offense at all man, but that seems like a bit of a hack -- a clever hack, but still... 🙂

I really think you should just use an action sheet or alert view and put your code in the delegate button handler -- the UI is modal with that method, and it's definitely the intended use of either of those UI components.

Good luck.

Cheers,
Ron

Jun 8, 2008 8:39 PM in response to Chamcham

make whatever is post the modal dialog a <UIActionSheetDelegate>
Create the dialog as per the UICatalog example

UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:dialogString
delegate:self cancelButtonTitle:nil destructiveButtonTitle:@"OK" otherButtonTitles:nil];

Show in view as per the example.

Create another function:

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex

Use this to signal that the modal is dismissed.

Jul 28, 2008 12:54 AM in response to Chamcham

This is an extremely frustrating problem in iPhone OS, given that is such a common UI requirement. What we need are simple equivalents of JavaScript's alert() and confirm() functions, which are properly modal. The delegate approach seems to assume you're only going to have a single context in which a view controller needs to confirm the user's intentions. And a shared delegate has no way of knowing which actions correspond with the given message unless you write a big switch statement that hinges on some global. But if your app has several actions that require confirmation, I don't see an elegant way to handle them with a single generalized utility function. How are we supposed to handle multiple contexts with this scheme?

Dec 26, 2008 3:12 PM in response to Chamcham

It's surprising how difficult this is to do on the iPhone. While it can be argued we should just adopt Apple's approach (putting the "second half" of any function that needs a UIAlertView into a delegate method) even though that approach results in ugly, unmaintainable code, there are good arguments other than aesthetics for having a truly (TRULY) modal UIAlertView.

In our case, about 75% of our app is ported C++ code that assumes (who wouldn't) that you can pop up an OK/Cancel dialog in the middle of a function to ask the user to decide how to continue when something unexpected happens. So ideally we'd like to take our existing C++ message box class and add some #if's to include code based on platform. This would allow the rest of the code to run.

If UIAlertView really works the way it's described in the documentation, then this is the only place in our entire app where we have to restructure shared code to uglify it for the iPhone. (Most of our really ugly code is in the iPhone-specific, Objective C portions of our program. We haven't had to uglify the code we're porting from Windows/WinMobile.)

The proposed NSRunLoop solution is the right idea, but it triggers an exception sometime after the UIAlertView is closed.

I've seen another solution where a private UIAlertView interface is exposed and used. This actually works but not especially well.

@interface UIAlertView (Synthesize)
- (void)setRunsModal:(BOOL)modal;
@end

Then invoke [alert setRunsModal:YES] before [alert show].

This works but seems to require a tap to get the attention of the alert view before pressing any buttons.

This should be documented and fixed. There are good reasons to support a truly modal UIAlertView.

Dec 26, 2008 5:38 PM in response to DesiredAliasGoesHere

First off, I mean no offense to you Windows programmers (I come from a .NET background myself). The fact is, Apple actually did this right. By providing an alert with a delegate you get much more flexibility than a Javascript (?!?!) alert. If you do things the Cocoa way (MVC, delegates, KVO, etc) as opposed to trying to do things the Windows way your code will be much cleaner and things will work the way you would expect. After embracing the Cocoa way I actually now do my Windows code in the same manner with delegates and such and avoid the code behind spaghetti that I used to write. Either do it all the way or roll your own with Cocoa. Doing things halfway won't get things working the way you want.

Jan 20, 2009 2:20 AM in response to orangekay

This isn't a platform debate. The way apple implemented is right - most of the time.

Here is a problem where I would need a blocking UIAlertView. As many developers have experienced, the available RAM on the iPhone runs low after a while.

The problem is, if your app uses a lot of memory (like when working with images) it may crash when the user starts it. In the log you will find a memory warning and the hint that the kernel did end the app. Restarting the iPhone solves the problem.

Now I know, the way to handle low memory is the didReceiveMemoryWarning where you can dealloc mem. My app has some images that are "loaded by the .nib" file, so without changing that and loading the images in code there is no roper way to react to the memory warning.

To stop making it look like a random crash, my idea was to simply present the user with an alertView to let them know about the problem and offer a solution (restart the iPhone). But this fails, because while the user get's to see the message (presented by an UIAlertView) the iPhone still loads the rest of the images in the background reducing the amount of memory even further and forcing the kernel to terminate the app.

Having a blocking version (in addition to the very usefull non blocking version) of the AlertBox (something like showModal) would be a simple solution. The iPhone could not load more stuff in the background, and I could gracefully quit the app after the user did read the message.

This thread has been closed by the system or the community team. You may vote for any posts you find helpful, or search the Community for additional answers.

Modal Alert

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple Account.