Search code examples
iphoneios5seguexcode-storyboard

iOS 5 Segue not working after the first execution


I'm creating an iOS5 application using the storyboard features. The basic structure is:

LoginScreen ---(segue)--> MyScreen ---(press on logout)------(segue back to login screen)-->LoginScreen

it's pretty simple. The way I manage the first segue is:

- (void) onResponse:(NSMutableDictionary *)response {
  NSLog(@"Login successful,token received");
  // if the Login was successful,store the token 
  NSUserDefaults* userPref = [NSUserDefaults standardUserDefaults];    
  [userPref setObject:[response objectForKey:@"Token"] forKey:@"AuthToken"];
  [userPref synchronize];
  //..and let the user getting in
  [self performSegueWithIdentifier:@"showHomeScreen" sender:nil];
}

Now,the strange thing is that the segue is correctly performed the first time,but,when I come back to the login screen after a logout the performSegueWithIdentifier: doesn't work anymore (no error messages,simply nothing happens). Not sure what's going on. Which might be the problem?

I attach a screenshot of the storyboard..you can see the loop in the top-right corner: enter image description here

thanks a lot!

Claus


Solution

  • It looks like that LoginVC is connected to more than one Segue.

    The best way to handle that Login process is to use a delegate for the Login ViewController. Then in the main VC, you check credentials or whatever and if needed call the performSegue for the LoginVC. When the Login is successful, you call the delegate method and the Main VC will dismiss the modal view. The LoginVC really shouldn't be part of the navigation or connected to any other Segues other than the one from the Main VC. I have a complete example if you need it, but this is easy to implement using delegate methods.

    Here ya go: LoginViewController.h:

    @protocol LoginViewControllerDelegate
        -(void)finishedLoadingUserInfo;
    @end
    
    @interface LoginViewController : UIViewController <UITextFieldDelegate>{
        id <LoginViewControllerDelegate> delegate;
    }
    

    LoginViewController.m:

    @synthesize delegate;
    
    - (void) onResponse:(NSMutableDictionary *)response {
      NSLog(@"Login successful,token received");
      // if the Login was successful,store the token 
      NSUserDefaults* userPref = [NSUserDefaults standardUserDefaults];    
      [userPref setObject:[response objectForKey:@"Token"] forKey:@"AuthToken"];
      [userPref synchronize];
      //..and let the user getting in
      [delegate finishedLoadingUserInfo];
    }
    

    In the Dashboard VC .m file:

    #pragma mark - LoginViewController Delegate Method
    -(void)finishedLoadingUserInfo
    {    
        // Dismiss the LoginViewController that we instantiated earlier
        [self dismissModalViewControllerAnimated:YES];
        
        // Do other stuff as needed
    }
    

    So the gist is to check for credentials when the app loads and if needed, call (in the Dashboard VC):

    [self performSegueWithIdentifier:@"sLogin" sender:nil];
    

    Then in the prepareForSegue method (in the Dashboard VC):

    -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
        if ([segue.identifier isEqualToString:@"sLogin"]) {
            LoginViewController *livc = segue.destinationViewController;
            livc.delegate = self; // For the delegate method
        }
    }
    

    Make sure to name the Segue sLogin or this won't work :)

    Storyboard