web-dev-qa-db-fra.com

IOS - Comment classer par programme en utilisant swift

Je crée une application qui utilise le SDK de Facebook pour authentifier les utilisateurs. J'essaie de consolider la logique de Facebook dans une classe séparée. Voici le code (dépouillé pour la simplicité):

import Foundation

class FBManager {
    class func fbSessionStateChane(fbSession:FBSession!, fbSessionState:FBSessionState, error:NSError?){
        //... handling all session states
        FBRequestConnection.startForMeWithCompletionHandler { (conn: FBRequestConnection!, result: AnyObject!, error: NSError!) -> Void in

            println("Logged in user: \n\(result)");

            let storyboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
            let loggedInView: UserViewController = storyboard.instantiateViewControllerWithIdentifier("loggedInView") as UserViewController

            loggedInView.result = result;

            //todo: segue to the next view???
        }
    }
}

J'utilise la méthode de classe ci-dessus pour vérifier les changements d'état de session et tout fonctionne correctement.

Q: Une fois que j'ai les données de l'utilisateur, comment puis-je passer à la vue suivante depuis cette classe personnalisée?

EDIT: Juste pour être clair, j'ai un segue avec un identifiant sur le story-board, et j'essaie de trouver un moyen de réaliser un segue d'une classe qui n'est pas le contrôleur de vue.

175
Shlomi Schwartz

Si votre séquence existe dans le storyboard avec un identificateur de séquence entre vos deux vues, vous pouvez simplement l'appeler par programme en utilisant:

performSegue(withIdentifier: "mySegueID", sender: nil)

Pour les anciennes versions:

performSegueWithIdentifier("mySegueID", sender: nil)

Vous pouvez aussi faire:

presentViewController(nextViewController, animated: true, completion: nil)

Ou si vous êtes dans un contrôleur de navigation:

self.navigationController?.pushViewController(nextViewController, animated: true)
320
Jérôme Leducq

Vous pouvez utiliser NSNotification

Ajoutez une méthode de publication dans votre classe personnalisée:

NSNotificationCenter.defaultCenter().postNotificationName("NotificationIdentifier", object: nil)

Ajouter un observateur dans votre ViewController:

NSNotificationCenter.defaultCenter().addObserver(self, selector: "methodOFReceivedNotication:", name:"NotificationIdentifier", object: nil)

Ajouter une fonction dans votre ViewController:

func methodOFReceivedNotication(notification: NSNotification){
    self.performSegueWithIdentifier("yourIdentifierInStoryboard", sender: self)
}
21
Rodrigo Otero

Si votre séquence existe dans le storyboard avec un identifiant de séquence entre vos deux vues, vous pouvez simplement l'appeler par programme à l'aide de

self.performSegueWithIdentifier("yourIdentifierInStoryboard", sender: self)

Si vous êtes dans le contrôleur de navigation

let viewController = YourViewController(nibName: "YourViewController", bundle: nil)        
self.navigationController?.pushViewController(viewController, animated: true)

Je vous recommanderai pour une deuxième approche à l'aide du contrôleur de navigation.

14
Manish Mahajan

Vous pouvez utiliser segue comme ceci:

self.performSegueWithIdentifier("Push", sender: self)
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
    if segue.identifier == "Push" {

    }
}
14
Ricky

Swift - fonctionne également avec SpriteKit

Vous pouvez utiliser NSNotification.

Exemple:

1.) Créez une séquence dans le storyboard et nommez l'identifiant "séquence"

2.) Créez une fonction dans le ViewController à partir duquel vous vous situez.

func goToDifferentView() {

    self.performSegue(withIdentifier: "segue", sender: self)

}

3.) Dans ViewDidLoad () de votre ViewController, vous créez l’observateur.

NotificationCenter.default.addObserver(self, selector: #selector(goToDifferentView), name: "segue" as NSNotification.Name, object: nil)

Mise à jour - La dernière fois que j'ai utilisé cela, je devais changer l'appel .addObserver en code suivant pour mettre les erreurs au silence.

NotificationCenter.default.addObserver(self, selector: #selector(goToDifferentView), name: NSNotification.Name(rawValue: "segue"), object: nil)

4.) Dans le ViewController ou la scène à laquelle vous vous inscrivez, ajoutez la méthode de publication à l’endroit où vous le souhaitez.

NotificationCenter.default.post(name: "segue" as NSNotification.Name, object: nil)

Mise à jour - La dernière fois que j'ai utilisé cela, je devais changer l'appel .post en code suivant pour mettre les erreurs au silence.

NotificationCenter.default.post(NSNotification(name: NSNotification.Name(rawValue: "segue"), object: nil) as Notification)
12
Timmy Sorensen

Ce que vous voulez faire est vraiment important pour les tests unitaires. En gros, vous devez créer une petite fonction locale dans le contrôleur de vue. Nommez la fonction à n’importe quoi, incluez simplement le performSegueWithIndentifier.

func localFunc() {
    println("we asked you to do it")
    performSegueWithIdentifier("doIt", sender: self)
}

Ensuite, changez votre classe d'utilitaires FBManager pour inclure un initialiseur qui prend un argument d'une fonction et une variable pour contenir la fonction de ViewController qui effectue la séquence.

public class UtilClass {

    var yourFunction : () -> ()

    init (someFunction: () -> ()) {
        self.yourFunction = someFunction
        println("initialized UtilClass")
    }

    public convenience init() {
        func dummyLog () -> () {
            println("no action passed")
        }
        self.init(dummyLog)
    }

    public func doThatThing() -> () {
        // the facebook login function
        println("now execute passed function")
        self.yourFunction()
        println("did that thing")
    }
}

(L'initiation commod vous permet de l'utiliser dans les tests unitaires sans exécuter la séquence.)

Enfin, là où vous avez // todo: segue à la vue suivante ???, mettez quelque chose comme suit:

self.yourFunction()

Dans vos tests unitaires, vous pouvez simplement l'invoquer comme suit:

let f = UtilClass()
f.doThatThing()

où doThatThing est votre changement de statut de fbsession et UtilClass est de FBManager.

Pour votre code actuel, passez simplement localFunc (sans parenthèse) à la classe FBManager.

2
Bill

Vous pouvez faire cela en utilisant la fonction performSegueWithIdentifier.

Screenshot

Syntaxe:

func performSegueWithIdentifier(identifier: String, sender: AnyObject?)

Exemple:

 performSegueWithIdentifier("homeScreenVC", sender: nil)
1
Jayprakash Dubey

Cela a fonctionné pour moi.

Tout d’abord, attribuez au contrôleur de vue de votre storyboard un ID de storyboard dans l’inspecteur d’identité. Utilisez ensuite l'exemple de code suivant (en veillant à ce que la classe, le nom du storyboard et l'ID de story board correspondent à ceux que vous utilisez):

let viewController:
UIViewController = UIStoryboard(
    name: "Main", bundle: nil
).instantiateViewControllerWithIdentifier("ViewController") as UIViewController
// .instantiatViewControllerWithIdentifier() returns AnyObject!
// this must be downcast to utilize it

self.presentViewController(viewController, animated: false, completion: nil)

Pour plus de détails, voir http://sketchytech.blogspot.com/2012/11/instantiate-view-controller-using.html meilleurs voeux

1
amdan