Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
458 views
in Technique[技术] by (71.8m points)

ios - Swift performSegueWithIdentifier not working

I am trying to switch view controllers after a user successfully logs in to their account, but it is not working correctly. I cant use a segue directly because if the login button is clicked it will go to that view controller regardless if the information is correct or not. I have tried everything that I know of with no success. This is the code I am trying.

   @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")
        }
    }

}

I have the storyboard ID set to "Test" and it is not switching view controller when the correct information is entered. Can somebody help me resolve my problem?

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

[Assuming that your code is not crashing, but rather just failing to segue]

At least one problem is:

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

should be:

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

Remember that all UI operations must be performed on the main thread's queue. You can prove to yourself you're on the wrong thread by checking:

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

ADDENDUM

If there's any chance self might become nil, such as getting dismissed or otherwise deallocated because it's not needed, you should capture self weakly as [weak self] not unowned, and use safe unwrapping: if let s = self { s.doStuff() } or optional chaining: self?.doStuff(...)

ADDENDUM 2

This seems to be a popular answer so it's important to mention this newer alternative here:

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

Note, from https://www.raywenderlich.com/76341/use-nsoperation-nsoperationqueue-swift:

NSOperation vs. Grand Central Dispatch (GCD)

GCD [dispatch_* calls] is a lightweight way to represent units of work that are going to be executed concurrently.

NSOperation adds a little extra overhead compared to GCD, but you can add dependency among various operations and re-use, cancel or suspend them.

ADDENDUM 3

Apple hides the single-threaded rule here:

NOTE

For the most part, use UIKit classes only from your app’s main thread. This is particularly true for classes derived from UIResponder or that involve manipulating your app’s user interface in any way.

SWIFT 4

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

Reference:

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...