iphone: UIAlertView not disappearing and blocking UIProgressView - iphone

I have a UIAlertView that asks a user whether they want to copy a bunch of contacts. After the user clicks "Continue," I want the AlertView to disappear to be replaced by a UIProgressView that shows the rate of loading.
Everything functions properly except that the alert remains on the XIB after the user clicks Continue, and it doesn't disappear until the entire process has run. As soon as it disappears, the UIProgressView bar appears but by then it has reached 100%.
How do I clear the UIAlertView off the screen immediately and show the progress bar growing instead.
Here's the code. Thanks for help.
-(IBAction)importAllAddressBook:(id)sender {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Import ALL Contacts" message:#"Do you want to import all your Address Book contacts? (Please note that only those with a first and last name will be transfered)" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Continue", nil];
[alert show];
[alert release];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
if (buttonIndex == 0) {
NSLog(#"NO STOP");
return;
}else {
NSLog(#"YES CONTINUE");
importAllContactsProgress.hidden = NO; // show progress bar at 0
[self importAllMethod];
}
}
// method to import all Address Book
-(void) importAllMethod {
importAllContactsProgress.progress = 0.0;
load names etc etc

You'll want to perform the perform the import on a background thread:
[self performSelectorInBackground:#selector(importAllMethod)];
Your import method is blocking the main thread and preventing any UI actions from occurring.

Related

UIAlertViewDelegate not acting as expected

I have a very simple process running where after each round of a simple game the scores are calculated, labels updated and all the normal, very simple stuff. I have a UIAlertView that informs the player of how s/he performed. I use a UIAlertViewDelegate to postpone all the updates, resetting of controls etc. till after the UIAlertView is dismissed. The methods are [startNewRound],[startOver] and [updateLabels]. It's fairly obvious what they all do. Anyway, when the user hits round ten, I've made another UIAlertView that informs the player that the game has ended and shows the overall score. Again, I hoped to use a delegate to postpone the resets till after the AlertView is dismissed. The only problem is, with the endGame AlertView, it seems to be using the first AlertView's delegate method causing the game to continue with a new round and not start from the beginning. I hope this makes sense. Anyway, here are snippets of my code.
if (round == 10){
UIAlertView *endGame = [[UIAlertView alloc]
initWithTitle: #"End of Game"
message: endMessage
delegate:self
cancelButtonTitle:#"New Game"
otherButtonTitles:nil];
[endGame show];
}
else {
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle: title
message: message
delegate:self
cancelButtonTitle:#"Next"
otherButtonTitles:nil];
[alertView show];
}
And then the delegate methods:
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
[self startNewRound];
[self updateLabels];
}
- (void)endGame:(UIAlertView *)endGame didDismissWithButtonIndex:(NSInteger)buttonIndex
{
[self startOver];
}
So there it is. As I mentioned, the endGame AlertView appears to be using alertView's delegate, thus not activating the [self startOver] method. All the methods are working, it's just the AlertView is using the incorrect delegate method. Regards, Mike
Change your code like this,
if (round == 10){
UIAlertView *endGame = [[UIAlertView alloc]
initWithTitle: #"End of Game"
message: endMessage
delegate:self
cancelButtonTitle:#"New Game"
otherButtonTitles:nil];
endGame.tag = 111;
[endGame show];
}
else {
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle: title
message: message
delegate:self
cancelButtonTitle:#"Next"
otherButtonTitles:nil];
alertView.tag = 222;
[alertView show];
}
and delegate method as,
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
if(alertView.tag == 111)
{
[self startNewRound];
[self updateLabels];
}
else if(alertView.tag == 222)
{
[self startOver];
}
}
You cant have two delegate method for dismisswithbuttonindex, you need to handle this situation with tag.
Give both alert view a different tag and check it on delegate object. Thus you can differentiat the both alert view.

How the UIActionSheet works?

When popping a view I want to save some data, by asking confirmation. I'm asking confirmation using UIActionSheet. But irrespective of my response in action sheet, the view is changing in background, it creates some problem for me to use the response. I'm using navigation controller to switch views. How can I solve this
TIA
Better option is to use uialertview for asking confirmation.To do this follow this step:
Insure your header file contains the following:
#interface YourViewController : UIViewController <UIAlertViewDelegate>
Now when asked confirmation add this code:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Message" message:#"Are You Sure" delegate:self cancelButtonTitle:#"YES" otherButtonTitles:#"NO", nil];
[alert show];
[alert release];
Now after pressing one button below delegate will be called so add in .m file of app
- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
// the user clicked one of the YES/NO buttons
if (buttonIndex == 0)
{
NSLog(#"NO button pressed");
}
else
{
//Save data here
NSLog(#"YES button pressed");
}
}
#PooLas If I understood you correctly, You use uiactionsheet for user confirmation, while in background (actually under actionsheet) you change view controllers. Well, you can't do that, because delegate must be attached to controller which shows it up (if i am wrong, correct me). So when you click button, you can only first dismiss actionsheet and then change view controller, but not opposite – PooLaS

Create an alert on any view controller from a method [duplicate]

This question already exists:
Closed 10 years ago.
Possible Duplicate:
Create an alert on any view controller after Facebook request:didFailWithError:
I have a method that gets called if a video upload to Facebook has failed. If that method is called then I would like for a UIAlertView to appear in any view controller that a user happens to be on at the time the upload fails.
Is this possible?
UIAlertView creates it's own UIWindow above your application's main window and makes it key and visible. Any UIAlertView created by your application should be visible on any view controller in your application's main window.
-(void)yourMethod{
UIAlertView *alert = [[UIAlertView alloc] init];
[alert setTitle:#"Failed to upload video"];
[alert setMessage:#"bla bla bla"];
[alert setDelegate:self];
[alert addButtonWithTitle:#"Ok"];
[alert show];
}
then you can have this method to control what happens after the user clicks a button in your alert:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
if (buttonIndex == 0 ){
//do something
}else if (buttonIndex == 1){
//if you add more buttons
//do something
}
}
if you have more alert-views, you could add a tag [alert setTag:(int)] to identify them in the -(void)alertView method with [alertView getTag]

Multiple alertviews in a single view?

I have an Iphone application in which when i am pressing a button it shows an alertview to chose the background.whichever background user is chosing will be played as the background of the audio clips.But now i need to add another alert before i am showing this alert for giving some warning.after that only i need to pop the second one.but i was done that chosing alert in the didappear of that viewcontroller and set it as a Uialertview delegate.and on the button actions i was doing different actions.Can anybody help me on achieving this?
proAlertView *loginav1=[[proAlertView alloc] initWithTitle:#"title" message:#"Choose a Background to play with this program?" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Field",#"Beach", #"Stars",nil];
[loginav1 setBackgroundColor:[UIColor colorWithRed:0.129 green:0.129 blue:0.129 alpha:1.0] withStrokeColor:[UIColor colorWithHue:0.625 saturation:0.0 brightness:0.8 alpha:0.8]];
[loginav1 show];
- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
// the user clicked one of the OK/Cancel buttons
if (buttonIndex == 0)
{
//[self play];
//moviePlayer.scalingMode=MPMovieScalingModeAspectFill;
if(actionSheet.tag==123)
{
[self backButtonPressed];
}
}
else if (buttonIndex == 1)
{
videoFile = [[NSBundle mainBundle] pathForResource:#"video-track" ofType:#"mp4"];
[self play];
moviePlayer.scalingMode=MPMovieScalingModeAspectFill;
}
how can i include another alert before this is my question?
Initialize first Alertview
UIAlertView *al1 = [[UIAlertView alloc] initWithTitle:#"Warning!" message:#"Warning Msg!!!" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles: nil];
al1.tag=1;
al1.delegate=self;
[al1 show];
Implement Delegate method
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
if(alertView.tag==1){
// implement button events for first Alertview
if(buttonIndex==1){
//First button clicked of first Alertview
UIAlertView *al2 = [[UIAlertView alloc] initWithTitle:#"Choose BG" message:#"Choose BG?" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"1",#"2",#"3", nil];
al2.tag=2;
al2.delegate=self;
[al2 show];
}
}
if(alertView.tag==2){
// implement button events for second Alertview
if(buttonIndex==1){
// First button clicked second Alertview.
}
}
}
Controller Class header
#interface ViewController : UIViewController<UIAlertViewDelegate>{
}
Hope this will fulfill your need !
You can do like this, first display warning message in alertview and when user click OK in alertview then in alertview delegate method write code to display second alertview where user can choose background.

How to immediately force view to draw itself after closing Alert View by the user?

the situation is like this:
if i don't have internet connection, i show UIAlertView to the user.
when the user press "try again", i call "do something".
the problem is the UIAlertView still show for seconds.after the user click "try again"
i tried like:
[self.view setNeedsDisplay];
but,it not works, cause even in the documents,if said the refresh will be
only when code control will return to the system, and that is not the case here.
thanking in advance.
///////////////////////////////////
if(somecondition)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"" message:#"NO INTERNET CONNECTION"
delegate:self cancelButtonTitle:nil otherButtonTitles:#"Try Again", nil];
[alert show];
[alert release];
return;
}
- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
// the user clicked one of the OK/Cancel buttons
[self DoSomthing];
}
I use this method to detect when the alert is dismissed, I added a line of code to hide it and spawn a new URLrequest, if that's what you need.
-(void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
alert.hidden=YES;
[webnews loadRequest:[NSURLRequest requestWithURL:home]];
}
The request uses my UIWebView 'webnews' and the NSURL 'home', you will have to adapt these of course.
If you do some lengthy process in the callback from the alert, it will not hide until that callback returns.
So in other words, your doSomething method should not directly try to reconnect to the internet, but just have it spawn off the asynchronous call for doing this.
EDIT:
You may delay/detach execution of doSomething with this line of code:
[self performSelector:#selector(doSomething) withObject:nil afterDelay:0];