0

Hi I have a application at the minute that currently has a split view controller. What I want to do is add a login screen to appear before the rest of the app appears or if that is not possible it could possibly appear in the left of the screen on the Navigation Controller.

In my app delegate it is currently

// Override point for customization after application launch.
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {

    //Grab storyBoard
   UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:@"MainStoryboard_iPad" bundle:nil];

    //Grab a reference to the UISplitViewController
    UISplitViewController *splitViewController = (UISplitViewController *)self.window.rootViewController;

    UINavigationController *navigationController = [splitViewController.viewControllers lastObject];
    //splitViewController.delegate = (id)navigationController.topViewController;

    //NEW IMPLEMENTATION BELOW

    //Grab a reference to the RightViewController and set it as the SVC's delegate.    
     RightViewController *rightViewController = (RightViewController *) [[splitViewController.viewControllers objectAtIndex:1] topViewController];

    splitViewController.delegate = rightViewController;

    //Grab a reference to the LeftViewController and get the first asset in the list.
    UINavigationController *leftNavController = [splitViewController.viewControllers objectAtIndex:0];

    LeftViewController *leftViewController = (LeftViewController *)[leftNavController topViewController];

    AssetTracking *firstAsset = [[leftViewController assets] objectAtIndex:0];

    //Set it as the RightViewController's monster.
    [rightViewController setAssetTracking:firstAsset];

    //Set the RightViewController as the left's delegate.
    leftViewController.delegate = rightViewController;


    }
    return YES;
}

I was trying to add this but it doesnt seem to work

 LoginViewController *lvc = (LoginViewController *) [storyBoard instantiateViewControllerWithIdentifier:@"login123"];
 lvc.modalPresentationStyle = UIModalPresentationFullScreen;
 [splitViewController presentViewController:lvc animated:NO completion:nil];

If I add it at the end I get the error when trying to run it

Warning: Attempt to present LoginViewController: 0x9b5c5a0 on UISplitViewController: 0x9b64120 whose view is not in the window hierarchy!

Is there anyway of getting this screen to run/appear. Currently the view on the storyboard is not linked to anything by a segue and I am just calling it by the identifier.

This is the method I use to verify the user

- (IBAction)enterCredentials
{

NSString *hashedPassword = @"";
hashedPassword = [self sha1:(passwordField.text)];

if ([[credentialsDictionary objectForKey:usernameField.text]isEqualToString:hashedPassword]) {

    if([rememberLogin isOn])
    {
        NSLog(@"save user details");

        if ([usernameField text ]){
            [keychain setObject:[usernameField text] forKey:(__bridge id)kSecAttrAccount];
        }
        // Store password to keychain
        if ([passwordField text]){
            [keychain setObject:[passwordField text] forKey:(__bridge id)kSecValueData];
        }
    }else
    {
        NSLog(@"not saving user details");
        [keychain resetKeychainItem];
    }

    usernameField.text = @"";
    passwordField.text = @"";


    //[self dismissViewControllerAnimated:NO completion:nil];
    [self performSegueWithIdentifier:@"loginCorrect" sender:self];
}
else {
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" message:@"The Username Or Password You Entered Is Incorrect" delegate:self cancelButtonTitle:@"Dismiss" otherButtonTitles:nil];
    [alert show];
}
}
Karl
  • 45
  • 7

1 Answers1

-1

From the error message, you can see that the UISplitViewController's view is not attached to the main UIWindow yet as you try to present the LoginViewController.

Try to postpone the code which presents modal LoginViewController. Maybe using dispatch_after to verify this idea. If it's the case, you should find the code a more suitable time to be called.

And maybe you should consider to set the LoginViewController as the rootViewController when it's needed. Thus you could hide the entire UISplitViewController.

For example:

// in application:DidFinishLaunchingWithOptions:
if (/* iPad idiom && login required */) {
    LoginViewController *lvc = (LoginViewController *) [storyBoard instantiateViewControllerWithIdentifier:@"login123"];
    self.window.rootViewController = lvc;
} else {
    // setup your UISplitViewController as usual
}
Egist Li
  • 624
  • 5
  • 9
  • So now if I set it as the rootViewController in the DidFinishLaunchWithOptions how do I get back to setting the other as my rootView when the user is verified. See above to see the method I use to verify them. I was trying to use a segue but that obviously wont work anymore – Karl Dec 11 '13 at 12:39
  • When the user is verified, you could let the appDelegate or some other responsible instance to be informed via delegate pattern or notifications. When the responsible instance is informed, it could swap the appDelegate's window.rootViewController back to UISplitViewController. – Egist Li Dec 11 '13 at 12:43
  • Sorry but could you explain how to do this? Thanks – Karl Dec 11 '13 at 12:46
  • One possible but may not the best solution is to add a delegate to the LoginViewController. When the the user is authenticated, just inform the delegate via calling delegation method, such as `- (void) didLogInSuccessfullyLoginViewController: (LoginViewController *) lvc;` And you could set appDelegate as the delegate of LoginViewController, and swap the rootViewController in the didLogInSuccessfullyLoginViewController: method. Check out this SO: http://stackoverflow.com/questions/6168919/how-do-i-set-up-a-simple-delegate-to-communicate-between-two-view-controllers – Egist Li Dec 11 '13 at 12:52