Peter Unger
Peter Unger

Reputation: 54

Modal view reappearing after dismissal

I am calling a login view modally in the view did load method in the root view controller, but when I dissmiss the modal view controller it just reappears! any suggestions? hears the code:

** .h **

//
//  FirstViewController.h
//  Voyager
//
//  Created by Peter Unger on 9/1/13.
//  Copyright (c) 2013 Penumbra Software. All rights reserved.
//

#import <UIKit/UIKit.h>
#import <Parse/Parse.h>

@interface FirstViewController : UIViewController

@end

@interface DefaultSettingsViewController :
UIViewController <PFLogInViewControllerDelegate, PFSignUpViewControllerDelegate>

@end

** .m **

//
//  FirstViewController.m
//  Voyager
//
//  Created by Peter Unger on 9/1/13.
//  Copyright (c) 2013 Penumbra Software. All rights reserved.
//

#import "FirstViewController.h"
#import <Parse/Parse.h>

@interface FirstViewController ()

@end

@implementation FirstViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
       }

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    PFLogInViewController *login = [[PFLogInViewController alloc] init];
    login.fields = PFLogInFieldsUsernameAndPassword | PFLogInFieldsLogInButton | PFLogInFieldsSignUpButton;
    login.delegate = (id)self;
    login.signUpController.delegate = (id)self;
    [self presentViewController:login animated:YES completion:nil];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)logInViewController:(PFLogInViewController *)logInController didLogInUser:(PFUser *)user {
    [self dismissViewControllerAnimated:YES completion:nil];
}

- (void)signUpViewController:(PFSignUpViewController *)signUpController didSignUpUser:(PFUser *)user {
    [self dismissViewControllerAnimated:YES completion:nil];
}

@end

Upvotes: 2

Views: 652

Answers (2)

Bergasms
Bergasms

Reputation: 2203

You have a loop there. When the modal controller is dismissed, the viewDidAppear method will be called on first view controller, which will launch the modal view again. You should put comments or break points at the launch code to help debug things like this.

@interface FirstViewController (){
BOOL has_shown_login_modal;
}
@end  


 - (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
    has_shown_login_modal = NO;
   }  


 - (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
   if(!has_shown_login_modal){
      PFLogInViewController *login = [[PFLogInViewController alloc] init];
     login.fields = PFLogInFieldsUsernameAndPassword | PFLogInFieldsLogInButton |        PFLogInFieldsSignUpButton;
     login.delegate = (id)self;
     login.signUpController.delegate = (id)self;
     [self presentViewController:login animated:YES completion:nil];
      has_shown_login_modal = YES;
   }
}

Upvotes: 0

Lucas Eduardo
Lucas Eduardo

Reputation: 11675

As @Bergasms already said, you have a loop. the viewDidAppear method is called everytime your viewController appears in the screen. So, when you resign the presented viewController, the first view controller was supposed to appear, calling then the viewDidAppear, which will present again the PFLogInViewController, creating a loop.

If you move the code to the viewDidLoad method, your modal will be called just once, as this method is called only when the viewController is allocated.

And if you want the user to do not see the first viewController, you may want to set the animation in the presentViewController:animated:completion: to NO.


Edit:

One person said in another question that you might get an error if you call another view controller inside viewDidLoad (although I have done this once, haven't checked the behavior of the error yet). If that's your case and you get an error, you would have to let the code in viewDidAppear.


And if somehow you still want use viewDidAppear, you can simply create a BOOL property that controls if the PFLogInViewController was already called or not. It will be something like this

@property(nonatomic, assign) BOOL isLogged; 

And

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    if (!self.isLogged)
    {
        self.isLogged = YES;
        PFLogInViewController *login = [[PFLogInViewController alloc] init];
        login.fields = PFLogInFieldsUsernameAndPassword | PFLogInFieldsLogInButton | PFLogInFieldsSignUpButton;
        login.delegate = (id)self;
        login.signUpController.delegate = (id)self;
        [self presentViewController:login animated:YES completion:nil];
    }
}

In this way, your PFLogInViewController will be called once.

Upvotes: 3

Related Questions