Search code examples
iosobjective-cxcode5

View controller won't return to previous view controller programmatically


The scenario is when the app first loads (controller A loads), it checks if an NSDefaultuser exist. If it does not exist then it sends it to (Controller B). In controller B the user enters his/her username then clicks ok. Now, NSDefault is saving the username and it should also redirect it back to the main view controller. Here is the code:

if([Username.text  isEqual: @""]) {
    [self showOkAlert:@"Username required"];
}
else if([Password.text isEqual:@""]) {
    [self showOkAlert:@"Password required"];
}
else  {
    //suppose that login was successfully.
    [self SaveCredentials];


    NSString * storyboardName = @"MainStoryboard";
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle: nil];
    UIViewController * vc = [storyboard instantiateViewControllerWithIdentifier:@"LatestNews"];
    [self presentViewController:vc animated:YES completion:nil];

}

Controller A:

- (void)LoadCredentials {
//load username
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *username = [defaults objectForKey:@"User"];

if(!username) {

    [self showAlert:@"user does not exist"];

    [self dismissViewControllerAnimated:YES completion:nil];

    NSString * storyboardName = @"MainStoryboard";
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle: nil];
    UIViewController * vc = [storyboard instantiateViewControllerWithIdentifier:@"Login"];
    [self presentViewController:vc animated:YES completion:nil];

}else{
    [self showAlert:@"user exists"]; 
    // for testing purposes I want it to reset when user logged in. Just so I know it resets. Later this method will be called from logout button.
    [self resetUsernameWhenLogout];       
}
}
-(void)resetUsernameWhenLogout {
//reset username when logout
NSDictionary *defaultsDictionary = [[NSUserDefaults standardUserDefaults]     dictionaryRepresentation];
for (NSString *key in [defaultsDictionary allKeys]) {
    [[NSUserDefaults standardUserDefaults] removeObjectForKey:key];
}
[[NSUserDefaults standardUserDefaults] synchronize];
}

- (void)viewDidLoad
{
    [self LoadCredentials];
}

Solution

  • There are a couple of possibilities here; Firstly, iOS8 seems to instantiate the VC's a lot earlier than in iOS7, so the Navigation tree isn't complete in viewDidLoad, You should only use viewDidLoad for additonal initialization. Try moving your code [self LoadCredentials]; } to viewWillAppear.

    Secondly, if you have a nav controller, you should be adding the new VC to the nav tree via the nav controller. If this is the case, try the code below.

      if([Username.text  isEqual: @""]) {
          [self showOkAlert:@"Username required"];
      }
      else if([Password.text isEqual:@""]) {
          [self showOkAlert:@"Password required"];
      }
      else  {
          //suppose that login was successfully.
          [self SaveCredentials];
    
         //This does not work - I receive a thread error not sure how to debug it 
          UIStoryboard *storyBoard = self.storyboard;
          UIViewController *targetViewController = [storyBoard instantiateViewControllerWithIdentifier:@"LatestNews"];
          UINavigationController *navController = self.navigationController;
        if (navController) {
            [navController pushViewController:targetViewController animated:YES];
        }
    
      }