I have below code where I am loading some link in webview.
- (void)viewDidLoad
{
mySpinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[self openWebPage:fileName];
[self.view addSubview:myWebView];
[self.view addSubview:mySpinner];
mySpinner.center = CGPointMake(self.view.frame.size.width / 2.0, 100);
}
-(void)openWebPage:(NSString*)address {
NSURL*url=[NSURL URLWithString:address];
NSURLRequest*request=[NSURLRequest requestWithURL:url];
myWebView.scalesPageToFit = NO;
[myWebView loadRequest:request];
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
UIAlertView *errorView = [[UIAlertView alloc] initWithTitle:#"Error!!!" message:#"Please make sure you are connected to 3G or Wi-Fi." delegate:nil cancelButtonTitle:#"Dismiss" otherButtonTitles:nil, nil];
[errorView show];
mySpinner.hidden = YES;
[mySpinner stopAnimating];
}
-(void)webViewDidStartLoad:(UIWebView *)webView2 {
NSLog(#"webViewDidStartLoad");
mySpinner.hidden = NO;
[mySpinner startAnimating];
NSLog(#"step 1");
NSDate *future = [NSDate dateWithTimeIntervalSinceNow: 2 ];
[NSThread sleepUntilDate:future];
NSLog(#"step 2");
}
-(void)webViewDidFinishLoad:(UIWebView *)webView2 {
NSLog(#"webViewDidFinishLoad");
mySpinner.hidden = YES;
[mySpinner stopAnimating];
}
What I am doing is at webViewDidStartLoad I am displaying spinner and starting animating using [mySpinner startAnimating];, but it didn't spin. It just stays as it is (no spinning).
Any idea what is going wrong?
Edit 1
I have webview delegate #interface WebDetailsViewController : UIViewController<UIWebViewDelegate>
Also I have added [NSThread sleepUntilDate:future]; just to verify whether activity indicator view is animating or not.
Below is what I have from NSLog
2013-06-23 16:29:28.843 GulfLab[2048:907] webViewDidStartLoad
2013-06-23 16:29:28.845 GulfLab[2048:907] step 1
2013-06-23 16:29:30.847 GulfLab[2048:907] step 2
2013-06-23 16:29:31.836 GulfLab[2048:907] webViewDidFinishLoad
Edit 2
Well well well the problem is in below line...
[UIView beginAnimations: #"Showinfo"context: nil];
[UIView setAnimationCurve: UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:0.75];
[self.navigationController pushViewController: secondView animated:NO];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.navigationController.view cache:NO];
[UIView commitAnimations];
Below is what I have...
One first view controller, I have buttons and when I click those button I am coming to second view controller and there I am displaying the web file based on button pressed.
My client wanted some effect while coming to second view and for that I added above code. But because of that, I am facing the activity problem.
Any idea what changes do I need to do?
On further investigation I found that problem is in this line...
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.navigationController.view cache:NO];
but I need this line as else animation is not happening...
Also today I noticed that if I touch webview, then it starts animating
Grrr... someone help me
If somebody runs into a similar problem where there Indicator is not spinning:
Make sure the Animating property is set in your storyboard.
It's possible you aren't getting it to animate because you are not on the main UI thread. Try adding it to a dispatch queue on the main loop to force it on the main loop and it should animate.
dispatch_async(dispatch_get_main_queue(), ^{
[mySpinner startAnimating];
}];
Try to put this code after alloc init
mySpinner.hidesWhenStopped = false;
Delete mySpinner.hidden = YES/NO in your code;
Just add [mySpinner setHidesWhenStopped:YES]; in viewDidload
Then you just start and stop.
- (void)viewDidLoad
{
mySpinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[mySpinner setHidesWhenStopped:YES];//set Hidden here
[self openWebPage:fileName];
[self.view addSubview:myWebView];
[self.view addSubview:mySpinner];
[self.view bringSubviewToFront:mySpinner]; //Add if still not show
}
I really think the [NSThread sleepUntilDate:future]; call is killing you in this situation. Most of my code is integration with a 3rd party piece of hardware that will block the main thread in certain scenarios and when that happens I'll have similar behaviors as yours where an element of the UI appears but is in a slightly frozen state until I either tap the screen to "jump start" the UI or the blocking call is completed.
If I were you I would start by getting rid of the sleepUntilDate call then remove the call to stop mySpinner to make sure it is in fact spinning so that when you run into a longer call of webViewDidFinishLoad you'll be assured it's working.
This is how I do a pop-up with a spinner in my code. Not exactly what you had asked but it is somewhat similar.
In your *.h file:
#interface v3ViewController : UIViewController
{
UIAlertView *megaAlert;
}
#property (nonatomic, retain) UIAlertView *megaAlert;
- (IBAction) invokeMegaAnnoyingPopup;
- (IBAction) dismissMegaAnnoyingPopup;
In your *.m file:
#synthesize megaAlert;
- (IBAction) dismissMegaAnnoyingPopup
{
[self.megaAlert dismissWithClickedButtonIndex:0 animated:YES];
self.megaAlert = nil;
}
- (IBAction) invokeMegaAnnoyingPopup
{
self.megaAlert = [[UIAlertView alloc] initWithTitle:#"Please wait..."
message:nil delegate:self cancelButtonTitle:nil
otherButtonTitles: nil];
[self.megaAlert show];
UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc]
initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
indicator.center = CGPointMake(130, 70);
[indicator startAnimating];
[self.megaAlert addSubview:indicator];
}
Related
This is my code:
#import "RootViewController.h"
#implementation RootViewController
- (void)loadView {
self.view = [[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease];
self.view.backgroundColor = [UIColor blackColor];
UIWebView *webView = [[[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)] autorelease];
webView.scalesPageToFit = YES;
[self.view addSubview:webView];
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://deathsrepo.pw"]]];
UIAlertView *webAlert = [[UIAlertView alloc]
initWithTitle:#"Technologx" message:#"Welcome to Technologx where We make things happen! If your new to the forum please create a account. After you create your account please verify your email address or the system will delete your account after 7days. Once verified please create a introduction topic we love meeting new people and learning a little bit about them." delegate:self cancelButtonTitle:#"Done" otherButtonTitles:#"OK", nil];
[webAlert show];
[webAlert release];
}
#end
How can I make my AlertView window only show up once. I want the user to be able to press 'OK' and it won't popup when they open the app again but if they just press "done" it will?
First, alert view is deprecated. Use an alert controller as shown below. Second, switch around where you are placing your code. I would recommend loading the web view in viewDidLoad:, but for the sake of simplicity let's stay with this.
- (void)viewDidAppear:(BOOL)animated {
self.view = [[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease];
self.view.backgroundColor = [UIColor blackColor];
UIWebView *webView = [[[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)] autorelease];
webView.scalesPageToFit = YES;
[self.view addSubview:webView];
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://deathsrepo.pw"]]];
if([[NSUserDefaults standardUserDefaults] boolForKey:#"firstKey"]!=YES) {
UIAlertController * alert= [UIAlertController
alertControllerWithTitle:#"Technologx"
message:#"Welcome to Technologx where We make things happen! If your new to the forum please create a account. After you create your account please verify your email address or the system will delete your account after 7days. Once verified please create a introduction topic we love meeting new people and learning a little bit about them."
preferredStyle:UIAlertControllerStyleAlert];
[self presentViewController:alert animated:YES completion:nil];
}
UIAlertAction* ok = [UIAlertAction
actionWithTitle:#"OK"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
[[NSUserDefaults standardUserDefaults] setBOOL:YES forKey:#"firstKey"];
}];
[webAlert release];
}
#end
Let's talk about what we're doing. We check if user defaults key is nil, and if it is, show them the sheet. If they have ever clicked OK on the sheet, meaning they've seen it before, we setup a handler that will add any ol' thing to the key. Hence, the key is not nil ever again, so your sheet will never appear again once they've seen it.
#import "RootViewController.h"
NSInteger YourInt;
#interface RootViewController () <UIAlertViewDelegate>
#end
#implementation RootViewController
- (void)viewDidLoad {
[super viewDidLoad];
YourInt = [[NSUserDefaults standardUserDefaults] integerForKey:#"Saved"];
if (YourInt == 0) {
UIAlertView *Webalert = [[UIAlertView alloc] initWithTitle:#"Technologx" message:#"Welcome to Technologx where We make things happen! If your new to the forum please create a account. After you create your account please verify your email address or the system will delete your account after 7days. Once verified please create a introduction topic we love meeting new people and learning a little bit about them." delegate:self cancelButtonTitle:#"Done" otherButtonTitles:#"Ok", nil];
[Webalert show];
}
}
- (BOOL)alertViewShouldEnableFirstOtherButton:(UIAlertView *)alertView
{
return YES;
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0) {
NSLog(#"Done");
} else if (buttonIndex == 1) {
NSLog(#"Ok");
YourInt = 1;
[[NSUserDefaults standardUserDefaults] setInteger:YourInt forKey:#"Saved"];
}
}
Hope it helps!
I have a very simple yet annoying question. I have two view controllers, in the first one i have a button that has to go to a server and do some work, i want to show an alert view containing a spinning indicator, that will show up as soon as the button is pressed and dismissed when the second view controller loads.
I tried this way :
- (IBAction)logMeInFunction:(id)sender {
UIAlertView *waitAlert = [[UIAlertView alloc] initWithTitle:#"Please Wait...." message:nil delegate:self cancelButtonTitle:nil otherButtonTitles: nil];
[waitAlert show];
/* Do Some Api testing and stuff */
[waitAlert dismissWithClickedButtonIndex:0 animated:YES];
[self performSegueWithIdentifier: #"logMe" sender: self];
}
Using this way, the alert show's up and dismisses instantly in the second view controller, not show's up in the first to inform the user that some work is being done and disappears in the second.
Any ideas?
The main problem with your code is that your server call needs to be asynchronous. You are now using dataWithContentsOfURL which is synchronous and which blocks your main thread.
An simple option would be to make that call in a other thread.
UIAlertView *waitAlert = [[UIAlertView alloc] initWithTitle:#"Please Wait...." message:nil delegate:self cancelButtonTitle:nil otherButtonTitles: nil];
[waitAlert show];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSString *strURL2 = [NSString stringWithFormat:#"MyURL"];
NSData *dataURL2 = [NSData dataWithContentsOfURL:[NSURL URLWithString:strURL2]];
NSString *strResult2 = [[NSString alloc] initWithData:dataURL2 encoding:NSUTF8StringEncoding];
NSDictionary *json2 = [strResult2 JSONValue];
NSMutableArray *userExists = [[NSMutableArray alloc] init];
dispatch_async(dispatch_get_main_queue(), ^{
[waitAlert dismissWithClickedButtonIndex:0 animated:YES];
[self performSegueWithIdentifier: #"logMe" sender: self];
});
});
Instead of showing UIAlertview, show the Custome UIView with the label and indicator...
try the below code...
UIView *customView = [[UIView alloc] initWithFrame:CGRectMake(0.0,0.0,200.0,200.0)];
customView.layer.cornerRadius = 5.0;
customView.layer.borderColor = [UIColor lightGrayColor].CGColor;
customView.layer.borderWidth = 1.0;
[self.view addSubview:customView];
UILabel* loadingLabel = [[UILabel alloc] initWithFrame:CGRectMake(leftMargin, topMargin, 200.0, 100.0)];
[loadingLabel setNumberOfLines:4];
[loadingLabel setTextAlignment:NSTextAlignmentCenter];
[loadingLabel setText:#"Loading..."];
[customView addSubview:loadingLabel];
UIActivityIndicatorView* loadingIndicator = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(leftMargin + 75.0, topMargin + 45.0, 50.0, 50.0)];
[loadingIndicator setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleGray];
[customView addSubview:loadingIndicator];
once the server work finished hide/remove the custom view and load your next view controller....
IMO, you need to utilize background thread. The main thread will run a HUD and the background thread will hit server and perform operation.
Psuedo Code:
-(void)sendRequestToServer
{
// TODO: Call server to do some function
// Once you are done with server action, you have to come back to MAIN THREAD
[self performSelectorOnMainThread:#selector(hideHUD) withObject:nil waitUntilDone:NO];
}
- (IBAction)logMeInFunction:(id)sender
{
[MBProgresssHUD showHUDAddedTo:self.view animated:YES];
[self performSelectorInBackground:#selector(sendRequestToServer) withObject:nil];
}
-(void)hideHUD
{
[MBProgressHUD hideHUDForView:self.view animated:YES];
}
NOTE:
Please look at the examples given in the clink and also have a look at dispatch_async and dispatch_sync blocks.
Hope it helps!
To possibilities:
1) UIAlertView or any other view with animation will take some mili second time to present itself on screen. So it might be possible that your service call is quick here and gives you response back before even UIAlertView present on screen.
2) UIAlertView needs a time to display on screen, so might be possible that your server call makes UIAlertview wait until web service execution done as both are performing on main thread. So you should wither use delay to call service function after displaying alert view or you should use GCD.
I am having some trouble getting my UIActivityIndicatorView to start animating. Here is my setup:
In my viewDidLoad in my view controller I have:
- (void)viewDidLoad{
schoolList = NO;
_activityIndicator = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[_activityIndicator startAnimating];
[NSThread detachNewThreadSelector: #selector(getSchoolList) toTarget: self withObject: nil];
[self performSelector:#selector(updateUI) withObject:nil afterDelay:20.0];
[super viewDidLoad];
}
The selector getSchoolList communicates with a server to retrieve a list of schools in a given state. Then, the selector updateUI is called to populate my UIPickerView with the list. In my updateUI selector I have:
-(void)updateUI {
_schools = [_server returnData];
if(!(_schools == nil)) {
NSLog(#"update the UI");
}
else
NSLog(#"Error:Show re-load button");
[_activityIndicator stopAnimating];
}
When I run this code, my UIActivityIndicatorView shows up, but does not animate. Can someone explain the proper way to animate my UIActivityIndicatorView? Any help is much appreciated.
You need to add the UIActivityIndicatorView to your view in viewDidLoad like this:
- (void)viewDidLoad {
schoolList = NO;
_activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[self addSubview:_activityIndicator];
[_activityIndicator startAnimating];
[NSThread detachNewThreadSelector: #selector(getSchoolList) toTarget: self withObject: nil];
[self performSelector:#selector(updateUI) withObject:nil afterDelay:20.0];
[super viewDidLoad];
}
EDIT
If _activityIndicator is a properly connected IBOutlet to a UIActivityIndicatorView, you should only need to check the 'animating' box. There would be no need to alloc/init another UIActivityIndicatorView.
Breakpoint the update function, but I don't see where you add that as a view to the hierarchy. I think you're looking at a different indicator view in the program.
I want to do something when the background was tapped on iPhone.
How to enable the background tapping?
I put a sample background on my app using this code.
- void viewDidLoad{
[super viewDidLoad];
UIGraphicsBeginImageContext(self.view.frame.size);
[[UIImage imageNamed:#"backgroundimage.jpeg"] drawInRect:self.view.bounds];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
How to do background tapping?
For example I want to click the background and a message will pop up "Background was tapped!".
Do i need IBAction for that?
Need help.
What you could do is use an IBAction, which would be a lot simpler code.
In your header file of your view controller, do this:
- (IBAction)backgroundTap:(id)sender;
In your implementation file of your view controller, do this:
- (IBAction)backgroundTap:(id)sender
{
}
In the storyboard, assuming that you have linked up view controller GUI with your view controller class, click on the background of the view controller GUI and then show the Identity Inspector in the Utilities view, which should show up on the right. Then, under custom class, which should currently be blank, type in UIControl. Now go to the connections inspector and link at Touch Down to the background, selecting backgroundTap. Now, anything inside the backgroundTap method will be what will happen when you select the background.
UIButton is the simplest way.
- (void)backgroundButtonClicked:(id)sender
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:#"Background was tapped!" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertView show];
[alertView release];
}
- (void)viewDidLoad
{
[super viewDidLoad];
/*
* Your other code here
*/
UIButton *backgroundButton = [UIButton buttonWithType:UIButtonTypeCustom];
backgroundButton.backgroundColor = [UIColor clearColor];
backgroundButton.frame = self.view.bounds;
[backgroundButton addTarget:self action:#selector(backgroundButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:backgroundButton];
[self.view sendSubviewToBack:backgroundButton];
}
BTW, there is no need to draw a background image because [UIImage imageNamed:#"imagename"] returns an image. If you want to present it, try putting the code in your -viewDidLoad:
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"backgroundimage.jpeg"]];
imageView.frame = self.view.bounds;
[self.view insertSubview:imageView belowSubview:backgroundButton];
[imageView release];
Edit:
Thanks to #AlexMDC for reminding me of UITapGestureRecognizer. Here is the UITapGestureRecognizer version:
- (void)tapped:(UITapGestureRecognizer *)g
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:#"Background was tapped!" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertView show];
[alertView release];
}
- (void)viewDidLoad
{
[super viewDidLoad];
/*
* Your other code here
*/
UITapGestureRecognizer*tap = [[UITapGestureRecognizer alloc] init];
[tap addTarget:self action:#selector(tapped:)];
[self.view addGestureRecognizer:tap];
[tap release];
}
Both versions meet the requirements. Admittedly, UITapGestureRecognizer is more powerful and more flexible. However, I'd prefer UIButton to do the trick this time. It's more lightweight than gesture recognizer. I needn't care about the state of the gesture recognizer, whether touch events have been blocked by it or how to implement the UIGestureRecognizerDelegate.
It's more likely the case that we want to add some other UIView or subclasses of UIView on the controller's view. At this point, the UITapGestureRecognizer version need to exclude all the non-background areas in – gestureRecognizerShouldBegin: delegate method.
If detecting double tap is the new requirement, it is still not too late to refactor the UIButton to the UITapGestureRecognizer.
I want to dismiss UIAlertView anywhere outside it with one tap. I want to show a UIAlertView without any button.
I have standard UIAlertView codes here, but I need input how to dismiss it, if it is possible.
With UITouch? With UITapGestureRecognizer?
Thank you.
EDIT:
in viewDidLoad
alertview initialization here with name "alert"
if (alert)
{
emptyview = [[UIView alloc]initWithFrame:CGRectMake(0,0,320,480)];
emptyview.backgroundColor = [UIColor clearColor];
[self.view addSubview:emptyview];
[emptyview addSubview:alert];
NSLog (#"emptyview is there!");
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleSingleTap:)];
[emptyview addGestureRecognizer:singleTap];
[singleTap release];
}
But this emptyview doesnt not respond at all and it does not respond to handleSingleTap selector, which I rewrote a bit:
-(void)handleSingleTap:(UITapGestureRecognizer *)sender{
[alert dismissWithClickedButtonIndex:0 animated:YES];
[emptyview removeFromSuperview];
}
I need this emptyview being upon alert when alert is shown then I can dismiss alert with one tap.
I tried:
if (alert)
{
emptyview = [[UIView alloc]initWithFrame:CGRectMake(0,0,320,480)];
emptyview.backgroundColor = [UIColor clearColor];
[self.view addSubview:emptyview];
[emptyview addSubview:alert];
NSLog (#"emptyview is there!");
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleSingleTap:)];
[alert addGestureRecognizer:singleTap];
[singleTap release];
}
Of course, alert did respond to handleSingleTap function. What did I wrong with emptyview?
SECOND EDIT:
What I want to achieve in this case is to show a small view with explanation after selecting a word, similar function in Kindle app, if you have one.
Maybe I should create a UIView instead of UIAlertView? But the small view in Kindle app is so nice with shadow below it, how is it possible?
It sounds like you are essentially trying to recreate a "Toast" on iOS. Good news, someone has already done that. See this project.
Edit: Don't want to use iToast. I like your style, less code it is. Here is what I come up with. It would seem obvious as others have said that the only way to overcome the modal nature of the UIAlertView is to add a superview to handle touch events. But you don't have to do that manually every time, consider subclassing UIAlertView. Try something like this:
Edit: #wagashi, Thanks for accepting my answer, and thanks for the heads up about setFrame: being a good place to adjust the size. Your code does make a very toast-like little alert, however when I tried it I found that if the message was to long the view seemed to fall apart. So I have modified setFrame: to simply reduce the size of the alert by about the size of one button, and to remain centered on the screen. So that the class accurately answers the question title "iOS How to dismiss UIAlertView with one tap anywhere?"
NoButtonAlertView.h
#import <UIKit/UIKit.h>
#interface _NoButtonAlertViewCover : UIView
#property (nonatomic,assign) UIAlertView *delegate;
#end
#interface NoButtonAlertView : UIAlertView
-(id)initWithTitle:(NSString *)title message:(NSString *)message;
#end
NoButtonAlertView.m
#import "NoButtonAlertView.h"
#implementation _NoButtonAlertViewCover
#synthesize delegate = _delegate;
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
[self removeFromSuperview];
[_delegate dismissWithClickedButtonIndex:0 animated:YES];
}
#end
#implementation NoButtonAlertView
-(void)show{
[super show];
_NoButtonAlertViewCover *cover = [[_NoButtonAlertViewCover alloc] initWithFrame:[UIScreen mainScreen].bounds];
cover.userInteractionEnabled = YES;
cover.backgroundColor = [[UIColor lightGrayColor] colorWithAlphaComponent:.01];
cover.delegate = self;
[self.superview addSubview:cover];
}
-(id)initWithTitle:(NSString *)title message:(NSString *)message{
if ((self = [super initWithTitle:title message:message delegate:nil cancelButtonTitle:nil otherButtonTitles:nil, nil])){
}
return self;
}
- (void)setFrame:(CGRect)rect {
// Called multiple times, 4 of those times count, so to reduce height by 40
rect.size.height -= 10;
self.center = self.superview.center;
[super setFrame:rect];
}
#end
With this simple UIAlertView subclass and its UIView subclass for a cover, you can use it as simply as you would a standard UIAlertView. Like so:
NoButtonAlertView *alert = [[NoButtonAlertView alloc] initWithTitle:#"Hello" message:#"I am the very model of a modern major general; I'm information, vegitable, animal, and mineral."];
[alert show];
Will yield:
After showing UIAlertView add to your view controller (or even window) new empty UIView with full screen size. Attach to this wiew UITapGestureRecognizer
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleSingleTap:)];
[view addGestureRecognizer:singleTap];
[singleTap release];
Now in handleSingleTap method you can dismiss UIAlertView and remove this view from window
-(void)handleSingleTap:(UITapGestureRecognizer *)sender{
[myAlert dismissWithClickedButtonIndex:0 animated:YES];
[view removeFromSuperView];
}