objective-c - unwind segue swift 4




Démarrer conditionnellement à différents endroits du storyboard depuis AppDelegate (7)

Après avoir essayé différentes méthodes, j'ai pu résoudre ce problème avec ceci:

-(void)viewWillAppear:(BOOL)animated {

    // Check if user is already logged in
    NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
    if ([[prefs objectForKey:@"log"] intValue] == 1) {
        self.view.hidden = YES;
    }
}

-(void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];

    // Check if user is already logged in
    NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
    if ([[prefs objectForKey:@"log"] intValue] == 1) {
        [self performSegueWithIdentifier:@"homeSeg3" sender:self];
    }
}

-(void)viewDidUnload {
    self.view.hidden = NO;
}

J'ai un storyboard mis en place avec le contrôleur de connexion et de la vue principale de travail, ce dernier est le contrôleur de vue vers lequel l'utilisateur est navigué lorsque la connexion est réussie. Mon objectif est d'afficher le contrôleur de vue principal immédiatement si l'authentification (stockée dans le trousseau de clés) est réussie et d'afficher le contrôleur de vue de connexion si l'authentification a échoué. Fondamentalement, je veux le faire dans mon AppDelegate:

// url request & response work fine, assume success is a BOOL here
// that indicates whether login was successful or not

if (success) {
          // 'push' main view controller
} else {
          // 'push' login view controller
}

Je connais la méthode performSegueWithIdentifier: mais cette méthode est une méthode d'instance de UIViewController, donc non appelable depuis AppDelegate. Comment est-ce que je fais cela en utilisant mon storyboard existant?

MODIFIER:

Le contrôleur de vue initial du Storyboard est maintenant un contrôleur de navigation qui n'est connecté à rien. J'ai utilisé le setRootViewController: distinction parce que MainIdentifier est un UITabBarController. Alors voici à quoi ressemblent mes lignes:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{        
    BOOL isLoggedIn = ...;    // got from server response

    NSString *segueId = isLoggedIn ? @"MainIdentifier" : @"LoginIdentifier";
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Storyboard" bundle:nil];
    UIViewController *initViewController = [storyboard instantiateViewControllerWithIdentifier:segueId];

    if (isLoggedIn) {
        [self.window setRootViewController:initViewController];
    } else {
        [(UINavigationController *)self.window.rootViewController pushViewController:initViewController animated:NO];
    }

    return YES;
}

Suggestions / améliorations sont les bienvenues!


C'est la solution qui a fonctionné n iOS7. Pour accélérer le chargement initial et ne pas faire de chargement inutile, j'ai un UIViewcontroller complètement vide appelé "DUMMY" dans mon fichier Storyboard. Ensuite, je peux utiliser le code suivant:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    UIStoryboard* storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];

    NSString* controllerId = @"Publications";
    if (![NSUserDefaults.standardUserDefaults boolForKey:@"hasSeenIntroduction"])
    {
        controllerId = @"Introduction";
    }
    else if (![NSUserDefaults.standardUserDefaults boolForKey:@"hasDonePersonalizationOrLogin"])
    {
        controllerId = @"PersonalizeIntro";
    }

    if ([AppDelegate isLuc])
    {
        controllerId = @"LoginStart";
    }

    if ([AppDelegate isBart] || [AppDelegate isBartiPhone4])
    {
        controllerId = @"Publications";
    }

    UIViewController* controller = [storyboard instantiateViewControllerWithIdentifier:controllerId];
    self.window.rootViewController = controller;

    return YES;
}

Etant donné que vous utilisez déjà un Storyboard, vous pouvez l'utiliser pour présenter l'utilisateur avec MyViewController, un contrôleur personnalisé ( ébauche de la réponse de followben ).

Dans AppDelegate.m :

-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    MyCustomViewController *controller = [self.window.rootViewController.storyboard instantiateViewControllerWithIdentifier:@"MyCustomViewController"];

    // now configure the controller with a model, etc.

    self.window.rootViewController = controller;

    return YES;
}

La chaîne passée à instantiateViewControllerWithIdentifier fait référence à l'ID Storyboard, qui peut être défini dans le constructeur d'interface:

Juste envelopper dans la logique au besoin.

Si vous commencez avec un UINavigationController, cette approche ne vous donnera pas de contrôle de navigation.

Pour «sauter en avant» à partir du point de départ d'un contrôleur de navigation configuré via le constructeur d'interface, utilisez cette approche:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    UINavigationController *navigation = (UINavigationController *) self.window.rootViewController;

    [navigation.visibleViewController performSegueWithIdentifier:@"my-named-segue" sender:nil];

    return YES;
}

Je suggère de créer un nouveau MainViewController qui est contrôleur de vue racine du contrôleur de navigation. Pour ce faire, maintenez simplement le contrôle, puis faites glisser la connexion entre le contrôleur de navigation et MainViewController, choisissez 'Relationship - Root View Controller' à partir de l'invite.

Dans MainViewController:

- (void)viewDidLoad
{
    [super viewDidLoad];
    if (isLoggedIn) {
        [self performSegueWithIdentifier:@"HomeSegue" sender:nil];
    } else {
        [self performSegueWithIdentifier:@"LoginSegue" sender:nil];
    }
}

N'oubliez pas de créer des segments entre MainViewController avec les contrôleurs d'affichage Home et Login. J'espère que cela t'aides. :)


Je suppose que votre storyboard est défini comme "storyboard principal" (clé UIMainStoryboardFile dans votre Info.plist). Dans ce cas, UIKit chargera le storyboard et définira son contrôleur de vue initial en tant que contrôleur de vue racine de votre fenêtre avant d'envoyer l' application:didFinishLaunchingWithOptions: à votre AppDelegate.

Je suppose également que le contrôleur de vue initial dans votre storyboard est le contrôleur de navigation, sur lequel vous voulez pousser votre contrôleur de vue principal ou de connexion.

Vous pouvez demander à votre fenêtre son contrôleur de vue racine et lui envoyer le message performSegueWithIdentifier:sender: :

NSString *segueId = success ? @"pushMain" : @"pushLogin";
[self.window.rootViewController performSegueWithIdentifier:segueId sender:self];

Mise en œuvre rapide de même:

Si vous utilisez UINavigationController comme point d'entrée dans le storyboard

let storyboard = UIStoryboard(name: "Main", bundle: nil)

var rootViewController = self.window!.rootViewController as! UINavigationController;

    if(loginCondition == true){

         let profileController = storyboard.instantiateViewControllerWithIdentifier("ProfileController") as? ProfileController  
         rootViewController.pushViewController(profileController!, animated: true) 
    }
    else {

         let loginController =   storyboard.instantiateViewControllerWithIdentifier("LoginController") as? LoginController 
         rootViewController.pushViewController(loginController!, animated: true) 
    }

SI le point d'entrée de votre storyboard n'est pas un UINavigationController :

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {


    //Your View Controller Identifiers defined in Interface Builder
    NSString *firstViewControllerIdentifier  = @"LoginViewController";
    NSString *secondViewControllerIdentifier = @"MainMenuViewController";

    //check if the key exists and its value
    BOOL appHasLaunchedOnce = [[NSUserDefaults standardUserDefaults] boolForKey:@"appHasLaunchedOnce"];

    //if the key doesn't exist or its value is NO
    if (!appHasLaunchedOnce) {
        //set its value to YES
        [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"appHasLaunchedOnce"];
        [[NSUserDefaults standardUserDefaults] synchronize];
    }

    //check which view controller identifier should be used
    NSString *viewControllerIdentifier = appHasLaunchedOnce ? secondViewControllerIdentifier : firstViewControllerIdentifier;

    //IF THE STORYBOARD EXISTS IN YOUR INFO.PLIST FILE AND YOU USE A SINGLE STORYBOARD
    UIStoryboard *storyboard = self.window.rootViewController.storyboard;

    //IF THE STORYBOARD DOESN'T EXIST IN YOUR INFO.PLIST FILE OR IF YOU USE MULTIPLE STORYBOARDS
    //UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"YOUR_STORYBOARD_FILE_NAME" bundle:nil];

    //instantiate the view controller
    UIViewController *presentedViewController = [storyboard instantiateViewControllerWithIdentifier:viewControllerIdentifier];

    //IF YOU DON'T USE A NAVIGATION CONTROLLER:
    [self.window setRootViewController:presentedViewController];

    return YES;
}

SI le point d'entrée de votre storyboard est un UINavigationController remplacez:

//IF YOU DON'T USE A NAVIGATION CONTROLLER:
[self.window setRootViewController:presentedViewController];

avec:

//IF YOU USE A NAVIGATION CONTROLLER AS THE ENTRY POINT IN YOUR STORYBOARD:
UINavigationController *navController = (UINavigationController *)self.window.rootViewController;
[navController pushViewController:presentedViewController animated:NO];