简体   繁体   中英

How to show UIAlertView in background thread in ipad app?

I need to show alert view while some code is executing in background. For this I have implemented the following code.

//this is loading alert  
-(void)showAlert:(NSString *)message {

//    UIAlertView *alert;
alert11 = [[UIAlertView alloc] initWithTitle:@"Updates" message:message delegate:self        
 cancelButtonTitle:@"OK" otherButtonTitles: nil];
   #ifndef IOS5_1
  [alert11 autorelease];
  #endif

[alert11 show];

}

 -(void) showUpdates1:(NSString *)data {
isUpdating = true;
VideoBrowserAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
[appDelegate initApplicationDefaults];
[self performSelectorOnMainThread:@selector(showAlert:) 
                       withObject:@"Please wait while Updating the view...."
                    waitUntilDone:YES];
[appDelegate openExhibitView1];
  //this is update completed alert
 [VideoBrowserAppDelegate addUpdateLog:@"Update is completed" showLog:TRUE     calledFrom:nil];

  }

But while coming to performSelectorOnMainThread(..), alert is shown but it is disappeared with in second. After that openExhibitView1() is completely executed and again update alert shown correctly. When we click on OK button of update alert again loading alert is displayed. But this is not fair. I need to show loading alert until openExhibitView1() is executed in background unless until we click on ok button.

I suggest you writing you own like AlertView. But do not forget that subclassing the alertView is prohibited on iOS.

I siggest you to create your own UIView subclass and implement methods showWithMessage, title and other. Compose the view and then display it.

Moreover if you insist on using the Alerts .. here is an interesting post that might help ...

Multithreading iOS - performing alerts

But my suggestion is to subclass the UIView with custom display animation. Example of animations:

  - (void)animateShow
{
    CAKeyframeAnimation *animation = [CAKeyframeAnimation
                                      animationWithKeyPath:@"transform"];
    
    CATransform3D scale1 = CATransform3DMakeScale(0.5, 0.5, 1);
    CATransform3D scale2 = CATransform3DMakeScale(1.2, 1.2, 1);
    CATransform3D scale3 = CATransform3DMakeScale(0.9, 0.9, 1);
    CATransform3D scale4 = CATransform3DMakeScale(1.0, 1.0, 1);
    
    NSArray *frameValues = [NSArray arrayWithObjects:
                            [NSValue valueWithCATransform3D:scale1],
                            [NSValue valueWithCATransform3D:scale2],
                            [NSValue valueWithCATransform3D:scale3],
                            [NSValue valueWithCATransform3D:scale4],
                            nil];
    [animation setValues:frameValues];
    
    NSArray *frameTimes = [NSArray arrayWithObjects:
                           [NSNumber numberWithFloat:0.0],
                           [NSNumber numberWithFloat:0.5],
                           [NSNumber numberWithFloat:0.9],
                           [NSNumber numberWithFloat:1.0],
                           nil];
    [animation setKeyTimes:frameTimes];
    
    animation.fillMode = kCAFillModeForwards;
    animation.removedOnCompletion = NO;
    animation.duration = 0.2;
    
    [self.layer addAnimation:animation forKey:@"show"];
}

    - (void)animateHide
    {
        CAKeyframeAnimation *animation = [CAKeyframeAnimation
                                          animationWithKeyPath:@"transform"];
        
        CATransform3D scale1 = CATransform3DMakeScale(1.0, 1.0, 1);
        CATransform3D scale2 = CATransform3DMakeScale(0.5, 0.5, 1);
        CATransform3D scale3 = CATransform3DMakeScale(0.0, 0.0, 1);
        
        NSArray *frameValues = [NSArray arrayWithObjects:
                                [NSValue valueWithCATransform3D:scale1],
                                [NSValue valueWithCATransform3D:scale2],
                                [NSValue valueWithCATransform3D:scale3],
                                nil];
        [animation setValues:frameValues];
        
        NSArray *frameTimes = [NSArray arrayWithObjects:
                               [NSNumber numberWithFloat:0.0],
                               [NSNumber numberWithFloat:0.5],
                               [NSNumber numberWithFloat:0.9],
                               nil];
        [animation setKeyTimes:frameTimes];
        
        animation.fillMode = kCAFillModeForwards;
        animation.removedOnCompletion = NO;
        animation.duration = 0.1;
        
        [self.layer addAnimation:animation forKey:@"hide"];
        
        [self performSelector:@selector(removeFromSuperview) withObject:self afterDelay:0.105];
    }

UIKit isn't thread safe, that means that it's better if you don't try. I tried by myself working with Alert View from a background thread ( I forgot to dispatch them on the main) and the behaviors are unexpectable, sometime a crash, sometimes it was displayed a really lot after the -show method.
The other point is that you should not display more than one alert at time, they are queued up. If you show an alert when another is displayed, the last one will cover the first, but after the dismissal it will show again the first.
Better you change the business logic, UIKit + background thread is a NO NO.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM