0

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.

Nimantha
  • 6,405
  • 6
  • 28
  • 69
Balakrishna
  • 166
  • 2
  • 13
  • first one disappears probably because second appears. It's the alertView property.. that first one hides second one shows, and then when second one canceled then first one popback. – rptwsthi Jun 26 '13 at 12:04
  • Also your question is wrong. You can't do UI thibgs on a background thread. – William Falcon Jun 26 '13 at 12:05
  • As @rptwsthi said, so you need to prevent the app from showing multiple alerts at the same time – Wain Jun 26 '13 at 12:05
  • UI Objects are not thread safe and should not be used on anything except the main thread. I'm not sure whether Apple would reject your app if they found a UI object running on something that wasn't the main thread, this is because the results can be unexpected so crashes could occur. – Popeye Jun 26 '13 at 13:17
  • Hi @rptewsthi, i need to show to alert message like while updating the content i need to show "updating alert message" and when complete the update i need to show update completed message. how can i achieve this – Balakrishna Jun 26 '13 at 13:32

2 Answers2

1

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];
    }
Nimantha
  • 6,405
  • 6
  • 28
  • 69
Radim Halfar
  • 536
  • 2
  • 6
  • 15
  • 1
    It's not prohibited, it's just not supported. I've successfully subclassed UIAlertView to support blocks, so that's definitely an option. – Scott Berrevoets Jun 26 '13 at 13:08
  • 1
    @Popeye: Yes, they do, and they never say it's not allowed. You even quote it yourself: "does not support subclassing". That doesn't mean it's not allowed. – Scott Berrevoets Jun 26 '13 at 13:20
  • 1
    "Well-known"...? Give me one example where someone's app got rejected just because it subclassed UIAlertView. Not because it modified its view hierarchy, ONLY because it subclassed it. Again, I have several apps in the store that have used this subclass, all of them got accepted (including subsequent updates to those apps). – Scott Berrevoets Jun 26 '13 at 13:30
  • 1
    @Popeye: I am just going to repeat myself and ask you to give me one example of someone who got an app rejected because s/he subclassed UIAlertView. "Clearly" not being able to read the documentation is your problem, not mine, as "not being supported" does not mean "not allowed". Also, I'll reiterate my other statement also, just in case you missed it: Apple approved a number of my apps + updates with the subclass in it. Subclassing it does not equal using system provided items incorrectly. – Scott Berrevoets Jun 26 '13 at 13:52
  • 1
    @Popeye: You know, I have used Google, and NOWHERE do I see any mention of an app being rejected for that. But whatever, if you want to do it the hard way, knock yourself out. Just know there's an easier way. – Scott Berrevoets Jun 26 '13 at 14:14
  • 1
    Sorry Scott is right, even if isn't a good idea to subclass UIAlertView or hack its views hierachy, there are tons of app that do that, tons of project on github, mine as well. Is not a good idea because Apple changes the implementation a lot of Times screwing hacks, swizzling and subclasses on each release of iOS, if you tried the 7 beta on app with hacked UIAlertView, picker etc you gonna have bad times – Andrea Jun 26 '13 at 18:47
  • from the docs [link to the docs !!! ](http://developer.apple.com/library/ios/#documentation/uikit/reference/UIAlertView_Class/UIAlertView/UIAlertView.html) **Subclassing Notes** 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. – Radim Halfar Jul 01 '13 at 13:34
0

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.

Andrea
  • 26,120
  • 10
  • 85
  • 131