webentwicklung-frage-antwort-db.com.de

Swift performSegueWithIdentifier funktioniert nicht

Ich versuche, die Ansichtscontroller zu wechseln, nachdem sich ein Benutzer erfolgreich bei seinem Konto angemeldet hat, aber es funktioniert nicht richtig. Ich kann einen Segue nicht direkt verwenden, da beim Klicken auf die Anmeldeschaltfläche dieser View-Controller aufgerufen wird, unabhängig davon, ob die Informationen korrekt sind oder nicht. Ich habe alles versucht, was ich weiß, ohne Erfolg. Dies ist der Code, den ich versuche.

   @IBAction func loginTapped(sender: AnyObject) {

    let username = usernameField.text
    let password = passwordField.text

    if username.isEmpty || password.isEmpty {
        var emptyFieldsError:UIAlertView = UIAlertView(title: "Please try again", message: "Please fill in all the fields we can get you logged in to your account.", delegate: self, cancelButtonTitle: "Try again")
        emptyFieldsError.show()
    }

    PFUser.logInWithUsernameInBackground(username, password:password) {
        (user: PFUser?, error: NSError?) -> Void in
        if user != nil {
            self.performSegueWithIdentifier("Klikur", sender: self)
        } else {
            if let errorString = error!.userInfo?["error"] as? String {
                self.errorMessage = errorString
            }

            self.alertView("Please try again", message: "The username password combiation you have given us does not match our records, please try again.", buttonName: "Try again")
        }
    }

}

Ich habe die Storyboard-ID auf "Test" gesetzt und der View Controller wechselt nicht, wenn die richtigen Informationen eingegeben werden. Kann mir jemand bei der Lösung meines Problems helfen?

Here is the code for the LoginViewControllerHere is the attributes panel for the KlikurTableViewController

37
Trenton Tyler

[Angenommen, Ihr Code stürzt nicht ab, sondern schlägt nur fehl.]

Mindestens ein Problem ist:

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

sollte sein:

dispatch_async(dispatch_get_main_queue()) {
    [unowned self] in
    self.performSegueWithIdentifier("Test", sender: self)
}

Denken Sie daran, dass alle UI-Vorgänge in der Warteschlange des Hauptthreads ausgeführt werden müssen. Sie können sich selbst davon überzeugen, dass Sie im falschen Thread sind, indem Sie Folgendes überprüfen:

NSThread.isMainThread() // is going to be false in the PF completion handler

[~ # ~] Nachtrag [~ # ~]

Wenn die Möglichkeit besteht, dass self nicht mehr verwendet wird, z. B. wenn Sie entlassen oder anderweitig freigegeben werden, weil dies nicht erforderlich ist, sollten Sie sich schwach als [weak self] Not unowned erfassen und sicheres Auspacken verwenden : if let s = self { s.doStuff() } oder optionale Verkettung: self?.doStuff(...)

ADDENDUM 2

Dies scheint eine beliebte Antwort zu sein, daher ist es wichtig, diese neuere Alternative hier zu erwähnen:

NSOperationQueue.mainQueue().addOperationWithBlock {
     [weak self] in
     self?.performSegueWithIdentifier("Test", sender: self)
}

Beachten Sie, von https://www.raywenderlich.com/76341/use-nsoperation-nsoperationqueue-Swift :

NSOperation vs. Grand Central Dispatch (GCD)

GCD [dispatch_ * calls] ist eine einfache Methode, um Arbeitseinheiten darzustellen, die gleichzeitig ausgeführt werden sollen.

NSOperation erhöht den Aufwand im Vergleich zu GCD geringfügig. Sie können jedoch Abhängigkeiten zwischen verschiedenen Vorgängen hinzufügen und diese wiederverwenden, abbrechen oder aussetzen.

ADDENDUM 3

Apple versteckt die Single-Thread-Regel hier:

HINWEIS

Verwenden Sie zum größten Teil UIKit-Klassen nur aus dem Haupt-Thread Ihrer App. Dies gilt insbesondere für von UIResponder abgeleitete Klassen oder für Klassen, bei denen die Benutzeroberfläche Ihrer App auf irgendeine Weise manipuliert wird.

Swift 4

DispatchQueue.main.async(){
   self.performSegue(withIdentifier: "Test", sender: self)
}

Referenz:

https://developer.Apple.com/documentation/uikit

67
BaseZen

Ich habe das gleiche Problem mit der Anmeldung. wahrscheinlich machen wir das gleiche Tutorial. Nach der Benennung Ihrer Segue-ID müssen Sie Folgendes ersetzen:

performSegueWithIdentifier("Klikur", sender: self)

mit:

dispatch_async(dispatch_get_main_queue()){

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

}

die Art der Abfolge muss im Storyboard-Bereich auf "Anzeigen (z. B. Drücken)" eingestellt sein. Hoffe es wird funktionieren.

18
Mette

Stellen Sie sicher, dass Sie Folgendes eingeben: self.performSegue(withIdentifier: ..., ...)

in viewDidAppear oder später. In viewWillAppear oder viewDidLoad funktioniert es nicht.

13
GregJaskiewicz

Die Segue-ID, die Sie an performSegueWithIdentifier(_:sender:) übergeben, muss genau mit der ID übereinstimmen, die Sie der Segue im Storyboard gegeben haben. Ich gehe davon aus, dass Sie einen Unterschied zwischen dem Anmeldeansichts-Controller und dem Erfolgsansichts-Controller haben, der so ist, wie er sein sollte. Ist dies nicht der Fall, ziehen Sie mit gedrückter Strg-Taste vom ersten zum zweiten Ansichts-Controller, wählen Sie das Segue-Symbol im Storyboard aus und setzen Sie die ID auf Klikur. Führen Sie nicht die Navigation über den Button-Klick durch, wie ein Kommentator sagte, da dies den Hauptzweck von Segues zunichte macht, nämlich visuelle Anzeige des Anwendungsflusses im Storyboard.

EDIT: Hier ist der Code für einen Login View Controller:

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var usernameField: UITextField!
    @IBOutlet weak var passwordField: UITextField!

    @IBAction func attemptLogin(sender: AnyObject) {
        if !usernameField!.text!.isEmpty && !passwordField!.text!.isEmpty {
            performSegueWithIdentifier("Klikur", sender: self)
        }
    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if "Klikur" == segue.identifier {
            // Nothing really to do here, since it won't be fired unless
            // shouldPerformSegueWithIdentifier() says it's ok. In a real app,
            // this is where you'd pass data to the success view controller.
        }
    }

}

Und ein Screenshot der Segue-Eigenschaften, über die ich spreche: enter image description here

8
NRitH

Swift 3.x

DispatchQueue.main.async(){
    self.performSegue(withIdentifier: "Klikur", sender: self)
}
7
Felecia Genet
DispatchQueue.main.async() {
    self.performSegue(withIdentifier: "GoToHomeFromSplash", sender: self)`  
}
4
ibk

Stellen Sie sicher, dass Sie das Perform-Segment auf einem sichtbaren View-Controller ausführen.

Dies ist ein Edge-Fall, aber mein Perform-Segue ist fehlgeschlagen, als ich versucht habe, es auf dem Ansichtscontroller auszuführen, der zu meinem UIPageViewController gehört, der zurzeit nicht sichtbar war. Es ist auch fehlgeschlagen, wenn ich versucht habe, den Segue für alle zu meinem UIPageViewController gehörenden Ansichtscontroller auszuführen, einschließlich des derzeit sichtbaren Ansichtscontrollers. Der Fix bestand darin, zu verfolgen, welcher Ansichtscontroller derzeit in meinem UIPageViewController sichtbar war, und nur die Übergabe auf diesem Ansichtscontroller durchzuführen.

1
Justin Domnitz

Ein Beispiel in einem Login. Wenn Sie sich nach dem Klicken auf eine Schaltfläche (Aktion) erfolgreich angemeldet haben, können Sie Folgendes verwenden:

self.performSegue(withIdentifier: "loginSucess", sender: nil)

Wenn Sie jedoch die App starten und die Anmeldeinformationen von Ihrem Schlüsselbund erhalten haben, müssen Sie diese als Teil des Theard verwenden:

DispatchQueue.main.async(){
    self.performSegue(withIdentifier: "sessionSuccess", sender: nil)
}
1
Ppillo