Swift performSegueWithIdentifier无效

时间:2015-08-30 02:29:13

标签: ios xcode swift parse-platform

我试图在用户成功登录到他们的帐户后切换视图控制器,但它无法正常工作。我不能直接使用segue,因为如果单击登录按钮,它将转到该视图控制器,无论信息是否正确。我已经尝试了所有我知道但没有成功的事情。这是我正在尝试的代码。

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

}

我将故事板ID设置为"测试"当输入正确的信息时,它不会切换视图控制器。有人可以帮我解决我的问题吗?

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

8 个答案:

答案 0 :(得分:66)

[假设你的代码没有崩溃,而是只是没有发生错误]

至少有一个问题是:

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

应该是:

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

请记住,必须在主线程的队列上执行所有UI操作。你可以通过检查来证明你自己错了!

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

<强>附录

如果有任何机会self可能变为零,例如因为不需要而被解雇或以其他方式解除分配,则应该将自我弱化为[weak self]而不是unowned,并使用安全解包:if let s = self { s.doStuff() }或可选链接:self?.doStuff(...)

ADDENDUM 2

这似乎是一个受欢迎的答案,所以在这里提到这个更新的替代方案很重要:

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

注意,来自https://www.raywenderlich.com/76341/use-nsoperation-nsoperationqueue-swift

  

NSOperation vs. Grand Central Dispatch(GCD)

     

GCD [dispatch_ * calls]是一种轻量级方式,用于表示将要同时执行的工作单元。

     

与GCD相比,NSOperation增加了一些额外的开销,但您可以在各种操作之间添加依赖关系并重新使用,取消或暂停它们。

ADDENDUM 3

Apple隐藏了单线程规则:

  

请注意

     

在大多数情况下,只能从应用程序的主线程中使用UIKit类。   对于从UIResponder或其派生的类来说尤其如此   涉及以任何方式操纵您的应用程序的用户界面。

SWIFT 4

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

参考:

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

答案 1 :(得分:18)

我在登录问题上遇到了同样的问题。可能我们做同样的教程。在命名segue标识符后,您需要替换:

performSegueWithIdentifier("Klikur", sender: self)

使用:

dispatch_async(dispatch_get_main_queue()){

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

}
需要将

类型的seque设置为&#34; show(例如Push)&#34;在故事板segue。 希望它能奏效。

答案 2 :(得分:12)

确保您放置: self.performSegue(withIdentifier: ..., ...)

在viewDidAppear或更高版本中。它无法在viewWillAppear或viewDidLoad中工作。

答案 3 :(得分:8)

您传递给performSegueWithIdentifier(_:sender:)的segue标识符必须完全与您在故事板中为segue指定的ID匹配。我假设您在登录视图控制器和成功视图控制器之间有一个segue,它应该是这样的;如果没有,则从第一个视图控制器中按住ctrl +拖动,然后在故事板中选择segue的图标并将其ID设置为Klikur。正如一位评论者所说,不要在按钮点击上执行导航,因为这违背了设置segues的主要目的,即提供应用程序的 visual 指示在故事板中流动。

编辑:这是登录视图控制器的代码:

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.
        }
    }

}

我正在谈论的segue属性的屏幕截图: enter image description here

答案 4 :(得分:7)

swift 3.x

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

答案 5 :(得分:4)

)

答案 6 :(得分:1)

检查以确保在可见的视图控制器上运行perform segue。

这是一个边缘情况,但当我尝试在属于我当前不可见的UIPageViewController的视图控制器上运行时,我的执行segue失败了。如果我试图在属于我的UIPageViewController的所有视图控制器上执行segue,包括当前可见的视图控制器,它也会失败。修复是跟踪我的UIPageViewController中当前可见的视图控制器,并且只在该视图控制器上执行segue。

答案 7 :(得分:1)

登录中的示例。单击按钮(操作)后,如果登录成功,可以使用:

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

但是如果您要启动应用程序并且从钥匙链获得凭据,则需要将其用作theard的一部分:

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