MBProgressHUD does not show when used with performSegueWithIdentifier - objective-c

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];
});

Related

MBProgressHUD fades before finishing load

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];
}];
}

UI issues while using blocks

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];
}

UILabel to appear for 3 seconds after UIButton is pressed

After I hit a pause button, I want a label to appear until the user taps on the screen. How do I do this?
So far I have this
- (IBAction)ButtonPausePressed:(id)sender {
PauseLabel.hidden = false (//how do i make it only visible until user taps?//)
if (GameEnd != true){
if ([GameUpdate isValid]){
[GameUpdate invalidate];
[BirdUpdate invalidate];
}else{
BirdUpdate = [NSTimer scheduledTimerWithTimeInterval:0.015
target:self
selector:#selector(UpdateBird)
userInfo:nil
repeats:YES];
GameUpdate = [NSTimer scheduledTimerWithTimeInterval:0.025
target:self
selector:#selector(GameUpdate)
userInfo:nil
repeats:YES];
}
}
}
- (IBAction)ButtonPausePressed:(id)sender {
PauseLabel.hidden = false
[self performSelector:#selector(hiddenLabel) withObject:nil afterDelay:3];
...
}
- (void)hiddenLabel{
PauseLabel.hidden = YES;
}
Try following
[your_view addSubview:your_label];
your_label.hidden = YES;
[your_label performSelector:#selector(setHidden:) withObject:#NO afterDelay:3];
Try like this:
-(void)viewDidLoad
{
UITapGestureRecognizer *singleTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(btnSingleClicked:)];
[singleTapGesture setDelegate:self];
singleTapGesture.numberOfTapsRequired = 1;
[self.view addGestureRecognizer:singleTapGesture];
}
-(void)btnSingleClicked:(UITapGestureRecognizer *)recognizer
{
if(recognizer.state == UIGestureRecognizerStateEnded && !self.PauseLabel.hidden)
{
[[UIApplication sharedApplication] beginIgnoringInteractionEvents];
[UIView animateWithDuration:3.0f // 3 sec to hide it
delay:0.0f
options:UIViewAnimationOptionCurveEaseOut
animations:^{
[self.PauseLabel setAlpha:0.0f];
}
completion:^(BOOL finished)
{
// remove from super view if needed.
// Now you can handle touch events etc
[[UIApplication sharedApplication] endIgnoringInteractionEvents];
}];
}
}
The idea behind the line is add a single tap gesture on your viewcontroller's view and if the pause label is displayed and a touch is happend on view check its state is ended and hide label with animation.
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
PauseLabel.hidden = YES;
});

Force landscape orientation in one view controller

In iOS 5 and 6 I was doing this in the viewWillAppear method in my view controller:
UIViewController *c = [[UIViewController alloc] init];
//To avoid the warning complaining about the view not being part of the window hierarchy
[[[TWNavigationManager shared] window] addSubview:c.view];
[self presentModalViewController:c animated:NO];
[self dismissModalViewControllerAnimated:NO];
[c.view removeFromSuperview];
I also added this method in the app delegate
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
return [[TWNavigationManager shared] supportedInterfaceOrientationsForTopViewController];
}
Which basically forwards that call to the top view controller.
That caused auto-rotation methods to be called for my view controller and then I was able to force landscape orientation for just that view controller.
Now in iOS 7 that code doesn't work anymore. A white view appears full-screen.
What would be the proper approach in iOS7?
Thanks in advance.
Had the same problem and managed to fix it by dismissing the presented modal view animated:YES.
[self dismissViewControllerAnimated:YES completion:nil];
Hope that helps!
My solution involves what Andrey Finayev suggested, but also I had to set another transition style otherwise I was getting blank screen after the dismiss animation finished.
UIViewController *mVC = [[UIViewController alloc] init];
mVC.modalPresentationStyle = UIModalPresentationFullScreen;
mVC.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self.navigationController presentViewController:mVC animated:NO completion:^{
[self.navigationController dismissViewControllerAnimated:YES completion:^{
}];
}];
To prevent the little "flashing" from mdonia solution, I added a dispatch_after and was able to dismiss the dummy modal viewController with animation:NO
UIViewController *dummyModalVC = [UIViewController new];
[dummyModalVC setModalPresentationStyle:UIModalPresentationFullScreen];
[dummyModalVC setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
[dummyModalVC.view setBackgroundColor:[UIColor purpleColor]];
[self presentViewController:dummyModalVC animated:NO completion:^{
double delayInSeconds = 0.001f;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[dummyModalVC dismissViewControllerAnimated:NO completion:^{}];
});
}];
Looks of course still like an ugly workaround, but I didn't found a better solution in the given timeā€¦ ;(

Objective-C: Adding a delay

I'm trying to add a short delay to my app. It's just the splash screen fade out so it won't affect any other functionality in the app (since nothing else is running). I've tried a variety of approaches with no success. (This is happening in viewDidLoad of a viewController):
C's sleep:
...
//add the splash screen
[self.view addSubview:splashScreen];
sleep(3);
[self fadeOut:splashScreen];
NSObject's performSelector (thought this would work because doesn't UIViewController inherit from NSObject?)
[self performSelector:#selector(fadeOut:) afterDelay:3];
NSTimeInterval:
//wait 3 seconds
NSTimeInterval theTimeInterval = 3;
[self fadeOut:splashScreen withADelayOf:&theTimeInterval];
Here is fadeOut (written to work with the NSTimeInterval example)
- (void) fadeOut:(UIView *)viewToToggle withADelayOf:(NSTimeInterval* ) animDelay {
[UIView setAnimationDelay:*animDelay];
[UIView animateWithDuration:0.25 animations:^{
viewToToggle.alpha = 0.0;
}];
}
I get the fadeOut but not the delay. Can someone nudge me in the right direction. Thanks.
you can try dispatch_after or animateWithDuration:delay:options:animations:completion:
double delayInSeconds = 0.5;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
//yourcode
});
or
[UIView animateWithDuration:0.175 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
//your code
}completion:^(BOOL completed){
//animation completion execution
}];
You should rely on this method if you want to animate some properties of your view with some delay:
+(void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion
Have a look to the ref doc here.
So your code could be something like this:
[UIView animateWithDuration:0.25 delay:3.0 options: UIViewAnimationOptionCurveLinear animations:^{
viewToToggle.alpha = 0.0;
} completion: nil];
Tiguero and J2TheC both pointed me in the exact direction I needed to go:
Here's the code I used in case someone else needs the assist:
//add the splash screen
[self.view addSubview:splashScreen];
//fade it out with a delay
[UIView animateWithDuration:0.75 delay:3.0 options:UIViewAnimationOptionCurveEaseIn
animations:^{
splashScreen.alpha = 0.0;
}
completion:^ (BOOL finished) {
//do something on end
}];
Do One thing:
Make an uiimageview ref in the Appdelegate and in the didfinishLunching do this:
// Dont assign the main viewcontroller to the windwo here.
{
img = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"splash.png"]];
img.frame = CGRectMake(0, 0, 320, 480);
[self.window addSubview:img];
[NSTimer scheduledTimerWithTimeInterval:3 target:self selector:#selector(removeSplash) userInfo:nil repeats:NO];
[self.window makeKeyAndVisible];
}
- (void)removeSplash{
[img removerFromSuperview];
self.window.rootViewController = self.viewController;
}