Hiding a Segue on Login process

2019-04-15 12:51发布

问题:

after finding a good solution about a missing Segue execution thanks to this post

I'm clashing against another problem: Following the approach described in the aforementioned post I'm performing the check for my auth token in the Dashboard VC and,if not set,I activate a segue pointing to the LoginVC exploiting the delegate mechanism in order to dismiss the view once the operation is completed. Now,the problem is that on the very first run I got the Dashboard VC show for a moment before the LoginVC gets displayed. I would like to show the Login screen immediately hiding (somehow) the Dashboard VC. In other words I want the user to not notice what's really going on underneath.

Any idea? This is my current storyboard setup

and I check for my credentials in the DashboardVC like that:

- (void)viewWillAppear:(BOOL)animated {
//check if the token is set,if not trigger the Login screen
NSString* token = nil;
NSUserDefaults* userPref = [NSUserDefaults standardUserDefaults];
token = [userPref objectForKey:@"AuthToken"];
if (token == nil) {
    NSLog(@"Token not present,Login required!");
    [self performSegueWithIdentifier:@"sLogin" sender:nil];
    [super viewWillAppear:NO];

}
//[super viewWillAppear:YES];
}


// if the Segue was triggered by the "Logout" button we erase the token otherwise 
// simply perform the login since there was no token at all
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

if ([sender tag] == 5) {
    NSLog(@"User selected Logout");
    //remove the token
    NSUserDefaults* userPref = [NSUserDefaults standardUserDefaults];
    [userPref removeObjectForKey:@"AuthToken"];
    [userPref synchronize];
    NSLog(@"Token removed.");
}

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

}

@ElJay,I might need your help again :)

Thanks everybody!

回答1:

I would put the code that check for the login token and performs the segue in viewDidLoad instead of waiting for the view to appear, which you say don't want.

if ([[NSUserDefaults standardUserDefaults] boolForKey:@"LoggedIn"] == NO) {
        [self performSegueWithIdentifier:@"Push LogIn" sender:self];
    }

and also if you are using a segue with animation then you will probably still see the rootviewController, so I solved this by creating a custom segue that uses no animation so the login viewController appears immediately.

.h file

@interface UIStoryboardSegueNoAnim : UIStoryboardSegue

@end

.m file

#import "UIStoryboardSegueNoAnim.h"

@implementation UIStoryboardSegueNoAnim

- (void)perform {
    [self.sourceViewController presentModalViewController:self.destinationViewController animated:NO];
}

@end


回答2:

I'm assuming you have the login button linked to the segue to the Dashboard VC in IB. Remove this trigger and attach the segue for the dashboardVC to the Login VC instead of the login button.

Then in your code if the authToken doesn't equal nil, then do the

[self performSegueWithIdentifier:@"sDashboard" sender:self];

So basically your code would then be

if (token == nil) {
    NSLog(@"Token not present,Login required!");
    [self performSegueWithIdentifier:@"sLogin" sender:nil];
    [super viewWillAppear:NO];

} else {
    [self performSegueWithIdentifier:@"sDashboard" sender:self];
}