The MBProgressHUD fades before fully loading on app that loads a large database.
I have searched for answers to this but I cannot work out what I need to do to fix this.
This is my current code
-(void)beginParsing {
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
hud.mode = MBProgressHUDModeIndeterminate;
hud.labelText = LOCALIZED(#"LOADING");
hud.detailsLabelText = LOCALIZED(#"LOADING2");
[self.view addSubview:hud];
[self.view setUserInteractionEnabled:YES];
[hud showAnimated:YES whileExecutingBlock:^{
_dictJSON = [self performParsing];
} completionBlock:^{
[hud removeFromSuperview];
[self.view setUserInteractionEnabled:YES];
[self setData:_dictJSON];
[self getCategories];
[self setFeaturedRestaurants];
[listView reloadData];
}];
}
Related
I am using MBProgressHUD to display a loading indicator on my app. When i want to change something at UI or i open a new screen inside block, i only see a blank white screen. Does anyone has an idea what am i missing in my code?
-(void)doSomething:(id)sender
{
HUD = [[MBProgressHUD alloc] initWithView:self.view];
[self.view addSubview:HUD];
HUD.delegate = self;
HUD.labelText = #"Please wait";
[HUD showAnimated:YES whileExecutingBlock:^{
NSDictionary* dictReturn = [ServerApi getItemDetails::itemId userId:userId;
NewScreenController* vc = [[NewScreenController alloc]init];
[self presentViewController:vc animated:YES completion:nil];
}];
}
MBProgressHUD doesn't execute the block in the main thread. That's why you shouldn't change UI there at all.
You should use the method with a completionBlock instead.
- (void)doSomething:(id)sender {
HUD = [[MBProgressHUD alloc] initWithView:self.view];
[self.view addSubview:HUD];
HUD.delegate = self;
HUD.labelText = #"Please wait";
dispatch_block_t executionBlock = ^{
self.dictReturn = [ServerApi getItemDetails:itemId userId:userId];
};
void (^completionBlock)() = ^{
NewScreenController *vc = [[NewScreenController alloc] init];
[self presentViewController:vc animated:YES completion:nil];
};
[HUD showAnimated:YES
whileExecutingBlock:executionBlock
completionBlock:completionBlock];
}
I have a submit button on my view controller which I'd like to..
Show MBProgressHUD for 3 seconds
Once complete, move to the next screen.
The code I have so far..
- (IBAction)submit:(id)sender
{
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
[hud setMinShowTime:3];
[hud setLabelText:#"Processing"];
[hud hide:YES];
[self performSegueWithIdentifier:#"showAuditViewControllerBravo" sender:self];
}
With this I don't see the MBProgressHUD at all. If I comment out the performSegueWithIdentifier I do. Please help.
you can do this with NSTimer
try this code
-(void)stopAnimationAndMove{
[MBProgressHUD hideAllHUDsForView:self.view animated:YES];
[self performSegueWithIdentifier:#"showAuditViewControllerBravo" sender:self];
}
- (void)viewDidLoad
{
[super viewDidLoad];
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
[hud setMinShowTime:3];
[hud setLabelText:#"Processing"];
[NSTimer scheduledTimerWithTimeInterval:3.0
target:self
selector:#selector(stopAnimationAndMove)
userInfo:nil repeats:NO];
}
with dispatch_after
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
[hud setLabelText:#"Progress"];
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 3.0 * NSEC_PER_SEC); // provide value as required. time here is 3 sec
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[MBProgressHUD hideHUDForView:self.view animated:YES];
[self performSegueWithIdentifier:#"showAuditViewControllerBravo" sender:self];
});
I have a modelViewController that contains a UIView animation. When the animation block finishes it calls itself, thus looping.
When I dismiss the modelViewController (dismissInfo) which calls [_starView removeFromSuperview], the function gets called over and over very rapidly with the NSLog line being printed multiple times a second.
#implementation InfoVC
{
NSArray *imgs;
NSString *currentImg;
}
- (void)viewDidLoad
{
[super viewDidLoad];
_imageview.contentMode = UIViewContentModeLeft;
_imageviewUnder.contentMode = UIViewContentModeLeft;
imgs = [NSArray arrayWithObjects:
#"01.jpg",
#"02.jpg",
#"03.jpg",
#"04.jpg",
#"05.jpg",
#"06.jpg",
nil];
_imgInt = (arc4random()%6);
[self initialImage];
}
- (void)viewWillAppear:(BOOL)animated{
}
- (void)viewDidAppear:(BOOL)animated{
NSLog(#"viewDidAppear");
}
- (void)initialImage
{
_starView.contentMode = UIViewContentModeLeft;
_imageviewUnder.contentMode = UIViewContentModeLeft;
currentImg = [imgs objectAtIndex:_imgInt];
UIImage *image = [UIImage imageNamed:currentImg];
_starView = [[UIImageView alloc] initWithImage:image];
// Size the image view to the image (it's bigger)
_starView.bounds = CGRectMake(0.0, 44.0, 416.0, 416.0);
NSLog(#"tarView.center %#", NSStringFromCGPoint(_starView.center) );
_starView.alpha=1;
int nextImgInt = _imgInt + 1 ;
if (nextImgInt>5)
{
nextImgInt=0;
}
NSString *nextImg = [imgs objectAtIndex:nextImgInt];
UIImage *nextImage = [UIImage imageNamed:nextImg];
[_imageviewUnder setImage:nextImage];
[self.view sendSubviewToBack:_imageviewUnder];
_imgInt++;
if (_imgInt>5) {
_imgInt=0;
}
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView animateWithDuration:7.6f
delay:0.1f
options:UIViewAnimationCurveLinear
animations:^{
[_starView setCenter:CGPointMake(112, 208)];
[_starView setAlpha:0.0f];
}
completion:^(BOOL finished){
[_starView removeFromSuperview];
[self initialImage];
}];
[self.view insertSubview:_starView atIndex:1];
}
- (void)visitTwitter
{
NSURL *URL = [NSURL URLWithString:#"http://twitter.com/"];
SVWebViewController *webViewController = [[SVWebViewController alloc] initWithURL:URL];
[self.navigationController pushViewController:webViewController animated:YES];
}
- (IBAction)dismissInfo:(id)sender
{
[self cleanup];
[self dismissModalViewControllerAnimated:YES];
}
- (void)cleanup
{
[_starView.layer removeAllAnimations];
[self.view.layer removeAllAnimations];
[_starView removeFromSuperview];
}
- (void)viewDidUnload
{
[self cleanup];
[super viewDidUnload];
}
#end
Make yourself an animating flag, set true in viewDidLoad, and false in cleanup. Then check it in your initialImage method:
if ( ! animating )
return;
This is the second time I've come across this. One possible cause is the method being initialised in viewDidLoad but the subview and image not being ready in time (it seems the first pass of the animation loop doesn't work adding a ghost to the machine).
I moved the call to ViewDidAppear, making sure to display an initialisation image to stop the white flash. At last an infinite animation in a modal window
- (void)viewDidLoad
{
[super viewDidLoad];
_imageview.contentMode = UIViewContentModeLeft;
_imageviewUnder.contentMode = UIViewContentModeLeft;
imgs = [NSArray arrayWithObjects:
#"01.jpg",
#"02.jpg",
#"03.jpg",
#"04.jpg",
#"05.jpg",
#"06.jpg",
nil];
_imgInt = (arc4random()%6);
currentImg = [imgs objectAtIndex:_imgInt];
UIImage *image = [UIImage imageNamed:currentImg];
[_imageviewUnder setImage:image];
}
- (void)viewDidAppear:(BOOL)animated{
[self initialImage];
}
- (void)initialImage
{
currentImg = [imgs objectAtIndex:_imgInt];
UIImage *image = [UIImage imageNamed:currentImg];
_starView = [[UIImageView alloc] initWithImage:image];
// Size the image view to the image (it's bigger)
_starView.bounds = CGRectMake(0.0, 44.0, 416.0, 416.0);
NSLog(#"initialImage");
_starView.alpha=1;
[self.view insertSubview:_starView atIndex:1];
int nextImgInt = _imgInt + 1 ;
if (nextImgInt>5)
{
nextImgInt=0;
}
NSString *nextImg = [imgs objectAtIndex:nextImgInt];
UIImage *nextImage = [UIImage imageNamed:nextImg];
[_imageviewUnder setImage:nextImage];
[self.view sendSubviewToBack:_imageviewUnder];
_imgInt++;
if (_imgInt>5) {
_imgInt=0;
}
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:7.6];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
//[UIView setAnimationDidStopSelector:#selector(initialImage) ];
[_starView setCenter:CGPointMake(112, 208)];
[_starView setAlpha:0.0f];
[UIView commitAnimations];
[self performSelector:#selector(initialImage) withObject:nil afterDelay:7.6];
}
- (IBAction)dismissInfo:(id)sender
{
[self cleanup];
[self dismissModalViewControllerAnimated:YES];
}
- (void)cleanup
{
[NSObject cancelPreviousPerformRequestsWithTarget:self];
[_starView.layer removeAllAnimations];
[self.view.layer removeAllAnimations];
[_starView removeFromSuperview];
}
If you just want to create a looping animation, the best thing to do is use the option: 'UIViewAnimationOptionRepeat'. For example:
[UIView animateWithDuration:2.0
delay:0.0f
options:UIViewAnimationOptionRepeat
animations:^{
[myUIViewThing setCenter:CGPointMake(myUIViewThing.center.x - 100, myUIViewThing.center.y)];
}
completion:nil];
I'm having a problem getting leaderboards to show. I think I have it right but I get this error in the log
Unbalanced calls to begin/end appearance transitions for <UIViewController: 0x105e39c0>.
here's my code to show and hide the view
- (void)showLeaderboard
{
GKLeaderboardViewController *leaderboardController = [[GKLeaderboardViewController alloc] init];
if (leaderboardController != NULL)
{ CCLOG( #" leaderboardController ok...");
tempVC = [[UIViewController alloc] init];
leaderboardController.leaderboardDelegate = self;
[[[CCDirector sharedDirector] openGLView] addSubview:tempVC.view];
leaderboardController.category = #"com.bluemesasoftware.housedefender.hightestscore";
leaderboardController.timeScope = GKLeaderboardTimeScopeAllTime;
leaderboardController.leaderboardDelegate = self;
[tempVC presentModalViewController: leaderboardController animated: YES];
}
}
- (void)leaderboardViewControllerDidFinish:(GKLeaderboardViewController *)viewController
{
[tempVC dismissModalViewControllerAnimated:YES];
[tempVC.view.superview removeFromSuperview];
[tempVC release];
}
[tempVC presentModalViewController: leaderboardController animated: NO];
[tempVC dismissModalViewControllerAnimated:YES];
This should work.
don't add the view to CCDirector's openglview
i assume you have this code in your AppDelegate...if so do this:
[window.rootViewControler.view addSubview:tempVC.view];
instead of
[[[CCDirector sharedDirector] openGLView] addSubview:tempVC.view];
also..move this code before presentModalViewController
In my UITableViewController subclass I want to prepare the tabular data and reload the table after the view has already appeared (the table therefore initially loads empty). In my app delegate I have methods to produce and remove an activity screen. My problem seems to be that the activity view presentation is being delayed until after the reloadData call has been made. I proved this by removing the hideActivity line and sure enough my activity view appeared simultaneously with the reloading of the table. Here's the viewDidAppear for my view controller...
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[(AppDelegate *)[[UIApplication sharedApplication] delegate] showActivity];
[self prepare];
[self.tableView reloadData];
[(AppDelegate *)[[UIApplication sharedApplication] delegate] hideActivity];
}
I'm assuming this may have to do with the views not redrawing mid-method, but don't remember this happening before. Any ideas?
...although I know they work, here's my activity methods. Maybe the way I'm doing these allows for some sort of delayed appearance...
- (void)showActivity
{
self.activityView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 480.0f)];
self.activityView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.75f];
UIActivityIndicatorView *spinner = [[[UIActivityIndicatorView alloc] initWithFrame:CGRectMake((320.0f / 2.0f) - (37.0f / 2.0f), (480.0f / 2.0f) - (37.0f / 2.0f) - (20.0f / 2.0f), 37.0f, 37.0f)] autorelease];
spinner.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge;
[spinner startAnimating];
UILabel *label = [[[UILabel alloc] initWithFrame:CGRectMake(0.0f, spinner.frame.origin.y + spinner.frame.size.height + 10.0f, 320.0f, 30.0f)] autorelease];
label.textAlignment = UITextAlignmentCenter;
label.text = #"Working";
label.textColor = [UIColor whiteColor];
label.backgroundColor = [UIColor clearColor];
[self.activityView addSubview:label];
[self.activityView addSubview:spinner];
[self.window addSubview:self.activityView];
}
- (void)hideActivity
{
[self.activityView removeFromSuperview];
[self.activityView release];
}
Your UI isn't updating until you return control to the runloop. You need to either perform the preparation of the data in a background thread, or return control to the runloop to update the UI before starting the preparation, like this:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[(AppDelegate *)[[UIApplication sharedApplication] delegate] showActivity];
[self performSelector:#selector(prepareData) withObject:nil afterDelay:0.0];
}
- (void)prepareData {
[self prepare];
[self.tableView reloadData];
[(AppDelegate *)[[UIApplication sharedApplication] delegate] hideActivity];
}