Calling presentModalViewController just after dismissModalViewControllerAnimated has problems - iphone

I have the code
- (void)matchmakerViewController:(GKMatchmakerViewController *)viewController didFindMatch:(GKMatch *)match
{
[menuViewController dismissModalViewControllerAnimated:YES];
[GameKitWrapper getSingleton].match = match;
match.delegate = [GameKitWrapper getSingleton].remotePlayer;
[menuViewController presentModalViewController:avatarSelectionViewController
animated:YES];
}
But I have the problem that the dismiss is working but not the present. When I changed dismissModalViewControllerAnimated:YES to dismissModalViewControllerAnimated:NO it worked but does not look nice.
Any help is appreciated.

#adam has the right idea, but you don't want to wait for some arbitrary delay. That's fragile because it might take any amount of time for the animation to complete. You want to wait for the previous view controller to actually finish dismissing. The best place in my experience to put this is in your current view controller's viewDidAppear:. That will be called after your modal has completely gone away. See this question for some example code addressing a similar problem.

Try waiting for a second....
- (void)matchmakerViewController:(GKMatchmakerViewController *)viewController didFindMatch:(GKMatch *)match
{
[menuViewController dismissModalViewControllerAnimated:YES];
[GameKitWrapper getSingleton].match = match;
match.delegate = [GameKitWrapper getSingleton].remotePlayer;
[self performSelector:#selector(presentModal) withObject:nil afterDelay:1.0];
}
- (void)presentModal {
[menuViewController presentModalViewController:avatarSelectionViewController
animated:YES];
}

Try calling:
[menuViewController dismissModalViewControllerAnimated:NO];
before calling:
[menuViewController presentModalViewController:avatarSelectionViewController
animated:YES];

Related

presentViewController doesn't do anything

I have a method called:
- (NSDictionary *)requestCompleted:(ASIHTTPRequest *)request{
As you probably guessed, it starts when i get a request back from a web server.
My issue is that the next command runs, but doesn't do anything…
[self presentViewController:loadingPageVC animated:YES completion:nil];
I feel like I forgot to init something but I can't anything wrong.
try this
dispatch_async(dispatch_get_main_queue(), ^{
[self presentViewController:loadingPageVC animated:YES completion:nil];
});

Strange warning dismissing modal view controller

I'm working on iOS 6.
My application has a standard navigation controller with embedded a CustomViewController.
In this controller I create a modal view like this:
-(IBAction)presentModalList:(id)sender {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
StationsListViewController *list = [storyboard instantiateViewControllerWithIdentifier:#"StationsListViewController"];
[list setStationsData: [self.stationsData allValues]];
[self presentModalViewController:list animated:YES];
}
The modal controller show perfectly but dismissing generates a warning.
The dismiss method in this controller is:
-(IBAction)backToMap
{
[self dismissModalViewControllerAnimated:YES];
}
The warning generated is Warning:
Attempt to dismiss from view controller < UINavigationController: 0x1ed91620 > while a presentation or dismiss is in progress!
Any clues about that?
Thanks
I realise this is a late answer but maybe this will help someone else looking for a solution to this, here is what I did:
-(IBAction)backToMap
{
if (![[self modalViewController] isBeingDismissed])
[self dismissModalViewControllerAnimated:YES];
}
For me, i found that line of code was being called multiple times, I couldn't find out why so this was the easiest fix.
Thanks JDx for getting me on the right track. I adapted it to form this solution, which will remove the warning without using functions that are deprecated in iOS 6:
-(IBAction)backToMap
{
if (![self.presentedViewController isBeingDismissed]) {
[self dismissViewControllerAnimated:YES completion:^{}];
}
}
Targeting iOS6, this is what worked for me:
if (![self.presentedViewController isBeingDismissed])
[self.presentedViewController dismissViewControllerAnimated:YES
completion:nil];
I found this approach to be unreliable - say one case in five I'd still see the error.
My solution was to use the completion block to set a flag which controls whether or not it's safe to dismiss - that way you don't need to check whether or not the view is being dismissed.
-(IBAction)presentModalView:(id)sender {
:
self.canDismiss = NO;
[self presentViewController:aVC animated:YES completion:^{
self.canDismiss = YES;
}];
:
}
In the bit of code where the dismiss occurs, just check the flag:
-(void)dismisser {
:
if (self.canDismiss) {
[self dismissViewControllerAnimated:YES completion:nil];
}
:
}
Hey presto, no more errors!
You can do whatever you want after the completion of the dismiss method as:
-(IBAction)backToMap
{
[self dismissViewControllerAnimated:YES
completion:^{
//Do something here
}];
}

Displaying the image for particular time interval

I have view controller with UIImageView . In view did load i want to set image on image view for particular time interval.After that image view should be cleared and application should switch to next screen. I have tried following code which is not working:
welcomeImage.image=[UIImage imageNamed:#"abc.png"];
sleep(5);
homeScreenController *controller=[[homeScreenController alloc]initWithNibName:#"homeScreenController" bundle:nil];
controller.modalTransitionStyle=UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:controller animated:YES];
In this case it is sleeping before view did load and it is not going to the next screen also. So what is wrong with the code?
Use the below code/..
- (void)viewDidLoad
{
[super viewDidLoad];
[self performSelector:#selector(goToNextView) withObject:nil afterDelay:5.0];
}
- (void)goToNextView
{
homeScreenController *controller=[[homeScreenController alloc]initWithNibName:#"homeScreenController" bundle:nil];
controller.modalTransitionStyle=UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:controller animated:YES];
}
The easiest solution is to fire a event after a time. I would recommend using performSelector.
- (void) hide {
//For example.
[self dismissModalViewController];
}
- (void) viewDidLoad {
//Setup my image.
[self performSelector:#selector(hide) withObject:nil afterDelay:3];
}
you can use NSTimer
something like this
- (void) viewDidLoad {
.......
NSTimer *timer = [[NSTimer scheduledTimerWithTimeInterval:(2.5)
target:self selector:#selector(hideImage)
userInfo:nil repeats:NO] retain];
....
}
- (void)hideImage
{
yourImage.hidden = YES;
}
Also, you made a sleep(5) inside the Main Thread, that's bad.
try something like
[self performSelectorOnBackground:#selector(hide) withObject:nil]
and do the thing you want (and the sleep(5)) inside the method -(void)hide like
-(void) hide {
sleep(5)
// ...
}
Good luck ;)

self.navigationItem setHidesBackButton:YES acting inconsistent

I am trying to hide the navigation bar 'back' button during an animation. When the animation completes, the button re-appears.
my code is as follows:
- (void) animateResults {
[self hideNavBarButtons];
[self animatePlayer1];
[self animatePlayer2];
[self performSelector:#selector(showNavBarButtons) withObject:nil afterDelay:3.0];
}
- (void) hideNavBarButtons {
[self.navigationItem setHidesBackButton:YES animated:YES];
}
- (void) showNavBarButtons {
[self.navigationItem setHidesBackButton:NO animated:YES];
}
This works fine on the simulator... but I get weird results on the device. It is very inconsistent, and stops hiding the 'back' button after a few tries. I am assuming I have some delegates messed up.. but I am lost. Any help is appreciated.
Thanks.

presentModalViewController in viewDidLoad on first launch

I've been searching around but unfortunately have had no luck.
My app requires the user to sign in/sign up the first time he or she launches the app. I know how to determine first launch (using NSUserDefaults) but whenever I try to present the modal containing the sign in/ sign up controls, nothing happens.
Here's what I have:
-(void)viewDidLoad {
[self showLogin];
[super viewDidLoad];
}
-(void)showLogin {
FlipsideViewController *controller = [[FlipsideViewController alloc] initWithNibName:#"AccountView" bundle:nil];
controller.delegate = self;
controller.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:controller animated:YES];
[controller release];
}
However, nothing happens. The main view just loads as normal. Any help is greatly appreciated.
-Giles
[UPDATE]
Fixed simply by using..
-(void)viewDidAppear:(BOOL)animated
{
}
instead of
-(void)viewDidLoad
{
}
Thanks anyway!
/idiocy
I had the same issue and ended up using viewDidAppear as well. The only problem with the viewDidAppear approach is that if you load other UIViewControllers on top, then reshow the base, then your setup code gets called over and over. I ended up having to add a boolean value (initialised to YES) to this view controller and check that value before deciding what to do. Hope this helps someone...
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:(BOOL)animated];
if(justLaunched)
{
justLaunched = NO;
if(settingsFileExists)
{
[self displayMainView];
}
else
{
[self displaySetupView];
}
}
}
How about using performSelector:withObject:afterDelay in the viewDidLoad function? That's how I do it, with a short delay of 0.1s.
And invoking this in the viewDidLoad isn't very safe : the sequence viewDidLoad / viewDidUnload can occur at runtime when the iPhone needs to release some views in order to get back some free memory.
The side effect of such sequence would be that your login controller would be shown...
As you said the viewDidAppear looks better but not simply put it at the end of the appDidFinishedLaunching the delegate of your UIApplication?