Multiple AlertViews - Remove the alertview that is behind another alertview - iphone

I think this scenario should be weird one but i am stuck up with this.
I am having a view lets say View1, which will show one or more alertviews.Alerts are stacked one above the other if they are untouched.
The problem comes here.
If i click the top most alert ,it should take me to a complete new view lets say View2. And it does. Now i am getting the remaining alerts still shown in View2. I do not want this to happen . How can i auto dismiss the pending alerts created from View1 which are currently being shown in View2 ?
Any help or any idea is really appreciated..
Thanks

Try this,
UIAlertView *autoAlertView = [[UIAlertView alloc] initWithTitle:#"Auto-dismissed Alert" message:#"This alert will be dismissed in 5 seconds." delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:nil];
[self performSelector:#selector(dismissAlert:) withObject:autoAlertView afterDelay:5];
[autoAlertView show];
[autoAlertView release];
-(void)dismissAlert:(UIAlertView *)alert {
[alert dismissWithClickedButtonIndex:0 animated:YES];
}

Not quite the answer to your question that you wanted, but...
Why do you have so many alerts? It sounds like you might be overusing them. Apple is quite clear in its Human Interface Guidelines about how you should use UIAlerts:
Avoid creating unnecessary alerts.
These alerts are usually unnecessary
if they:
Merely increase the visibility of some information, especially
information that is related to the
standard functioning of your
application.
Instead, you should design an
eye-catching way to display the
information that harmonizes with your
app’s style.
Update users on tasks that are progressing normally.
Instead, consider using a progress
view or an activity indicator to
provide progress-related feedback to
users (these methods of feedback are
described in “Progress View” and
“Activity Indicator”).
Ask for confirmation of user-initiated actions.
To get confirmation for an action the
user initiated, even a potentially
risky action such as deleting a
contact, you should use an action
sheet.
Inform users of errors or problems about which they can do nothing.
Although it might be necessary to use
an alert to tell users about a
critical problem they can’t fix, it’s
better to integrate such information
into the UI, if possible. For example,
instead of telling users every time a
server connection fails, display the
time of the last successful
connection.
If you're overusing alerts: don't. Then your original question may become moot.

You can dismiss the other UIAlertViews programmatically using:
- (void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated
You'll need to store a reference to them at creation to do this.

Thanks, guys! I wrote my own substitute for UIAlertView. I'm putting halftransparent UIView with frame (0, 0, 320, 480) to avoid user interaction while my custom alert still says "Please wait", and above this background view I'm putting this custom alert which is just basic UIView with UIActivityIndicatorView on it
P.S. Don't judge me for my english, i'm russian

Related

Displaying UIAlertView from a non-view class

I'm looking at a friend's code and not sure how this works. There's a singleton that talks to a web service to download data. The WebServiceObject is a subclass of NSObject. The download comes from a click on the home page which is a UIViewController.
In the WebServiceObject, when something goes wrong, he does:
UIAlertView *alert = [[UIAlertView alloc] init...];
[alert show];
The alert shows. How does that alert show though since the code that executes it is a non-view object? The reason I'm asking is because I want to remove that alert when the network comes back on. Since the network observing is happening in the WebServiceObject, I'm not sure how to access the UIAlertView object. I thought in other code I've done, that I would do something like
[self.view viewWithTag:NETWORK_ALERT_TAG];
or something to that affect. Is this because the view code is in the model code and instead I should change his code to post a notification to the view code to display the alert instead and grab it that way? Thanks a bunch!
UIAlertView’s -show method creates its own window, overlaid on top of the app’s window, in which to display itself; as such, it isn’t part of the app’s view hierarchy. To hide it, you’ll need a reference to the alert view itself, maybe exposed as a property on your WebServiceObject.
It sounds like you want to have the UIAlertView without any buttons, I found this nice tutorial that presents a "Please Wait Alert"
http://mobiledevelopertips.com/user-interface/uialertview-without-buttons-please-wait-dialog.html
I think it will help you achieve what you want, if you don't want the user to be able to dismiss the alert

Custom UIAlertView with Custom Buttons

I need to show a Custom UIAlertView which is going to have an image as a background and two Custom Buttons which will be not the regular UIAlertView Buttons. These buttons will be customized as well and would have their own Artwork.
The example above has a background but I also want to add Custom Button on it.
I am following this guide but I don't think it address the Custom Button handling.
How to do that? Any ideas?
Apple doesn't appear to like you overly-customising UIAlertView, and I've heard of a number of occasions where they've declined an app going into the app store because of it.
Because of the extent of customisation you're after, I suggest you create your own new Alert class that animates in and has a background shadow etc with buttons that you can customise the location/look of.
I found this blog post by Jeff LaMarche to be really helpful in making custom alert views: http://iphonedevelopment.blogspot.com/2010/05/custom-alert-views.html. He goes through the steps of making a custom class since modifying UIAlertView can cause App Store rejection (however he warns that using custom techniques can still cause HIG violations, but I doubt they will for what you're trying to do). By the time you're done, you'll have a custom alert view class that can be added in much the same style as UIAlertView:
At this point, we're done. We can now
use this custom alert view exactly the
same way we use UIAlertView:
CustomAlertView *alert = [[CustomAlertView alloc] init];
alert.delegate = self;
[alert show];
[alert release];
He creates a custom text input view. Obviously, in your case, you would want to use a different background and instead of adding a text field you'd stick to just the buttons. Since he makes custom buttons in his view too it should cover all your needs, if not more.
Unfortunately Apple does not allow subclassing UIAlertView:
The UIAlertView class is intended to be used as-is and does not
support subclassing. The view hierarchy for this class is private and
must not be modified.
The easiest way would be to create your own class with similar behavior.
Here's an example:
http://iosdevtricks.blogspot.com/2013/04/creating-custom-alert-view-for-iphone.html

what is good practice using UIAlertView with UIActivityIndicator

I've read a lot here about misusage of UIAlertView and the fact that Apple may reject an app where UIAlertView is overused.
In my app I'm writing I have to update data rarely via online request and recalculating internal data structures. While this is in effect and running in a second thread I don't want that the user touches the GUI and the app's current settings etc. So I decided to show an UIAlertView with UIActivityIndicator and a UIProgessView for some seconds which is dismissed automatically when background work is done.
Do you think that it is a reason against HIG rules? If so do you have suggestions for good practice on this kind of work flow?
Cheers,
Konran
Instead of a UIAlertView, I'd use MBProgressHUD. It looks nicer and has a built in activity indicator. Apple uses a similar component in some of their apps.
https://github.com/matej/MBProgressHUD
I don't think an alertView should be used to stop a user from interacting with the screen. What you can easily do is add a "mask" on top of your content. Create a view; give a background color of .5 alpha black, and add it as a subview of your main view. This will dim everything else, and stop the user from interacting with it.
I have used an alert view with integrated activity indicator in a couple of apps and none of them was rejected from entering the AppStore. If you don't display any button inside the alert view the user won't even consider it as an alert view, so I don't see any problem with that.

Why releasing an UIAlertView just afer showing it whereas it is not a blocking method?

I have been studying how to display a modal view with UIAlertView for a few hours and I understood that showing it does not "block" the code (the modal window is displayed and the program keeps running - we must use delegate to catch the selected actions on this modal window). Then I studied several examples and noticed that every example always release the modal window just after showing it. How can this work properly since the view will be released instantly as the code does not stop ?
Here is the example (there are many others on Google):
[[UIAlertView alloc] initWithTitle:#"Title" message:#"Message..." delegate:NULL cancelButtonTitle:#"OK" otherButtonTitles:NULL];
[alert showModal];
[alert release];
Thanks for your help,
Apple 92
I'm not sure where you're getting -showModal from (the usual method is just -show), but that act adds the alert to the view hierarchy. When a view is added as a subview of another view (I believe in this case it's a system-level view that is being added to) it's retained automatically, so you don't have to.
The alloc method will return you an instance that has a retain count of 1.
The showModal method probably retains the alert view so it remains on screen (and retained) until a button is tapped. It makes sense to me, since you are presenting it as a modal window, so it doesn't have a "parent", that is responsible of releasing it.

How do I code a green button in UIActionSheet?

I am using the code:
{
randomstatus=0;
msg=[[NSString alloc]initWithFormat:#"Good job, do you want to continue?"];
UIActionSheet *actionSheet=[[UIActionSheet alloc]initWithTitle:msg delegate:self cancelButtonTitle:#"No" destructiveButtonTitle:#"Yes" otherButtonTitles:nil];
[actionSheet showInView:self.view];
[actionSheet release];
[msg release];
}
I don't want to change the code, but I need the "destructiveButton" to be green instead of red. Is this possible, or do i need to use a different button?
There is no "standard" way of changing the appearince of the buttons. Any ways you use will essentially be hacks and may break in the future if Apple change the UIActionSheet component. They may also get your app rejected if they upset the App-Store gods.
I think the most future-proof way of acheiving this is to create your own action sheet class from scratch, ie not subclassing UIActionSheet (as this may break in the future). Although this may be a bit more work up-front than some hack, the extra flexibility you'll gain will come in useful in the future.
This shouldn't be too difficult. You'll need a view which is the background for the action sheet, which you can get by taking a screenshot of a standard UIActionSheet and some photoshopping. Then add your custom buttons as sub-views. A bit of animation for bringing up the view and you're done.
I would aim to have your class implement all the methods the UIActionSheet does, as well as firing off the methods UIActionSHeetDelegate expects. This way you'll be able to substitue it in anywhere you'd otherwise use a native UIActionSheet
Unfortunately there aren't any officially provided methods for customizing UIActionSheet buttons.
However you can access the subviews of the UIActionSheet (which could break in a future iPhone OS update), or add a new view with a button that covers the original destructive action button (once again, this may break).
While not directly related to changing the color of a button on a UIActionSheet, this previous question: iPhone Disabling UIActionSheet buttons demonstrates a few ways you could add custom views to a UIActionSheet.