ios Swift performSegueWithIdentifier 不起作用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32292600/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 07:26:52  来源:igfitidea点击:

Swift performSegueWithIdentifier not working

iosxcodeswiftparse-platform

提问by Trenton Tyler

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.

我试图在用户成功登录到他们的帐户后切换视图控制器,但它无法正常工作。我不能直接使用 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")
        }
    }

}

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?

我将情节提要 ID 设置为“测试”,并且在输入正确信息时它不会切换视图控制器。有人可以帮我解决我的问题吗?

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

这是 LoginViewController 的代码Here is the attributes panel for the KlikurTableViewController

回答by BaseZen

[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:

请记住,所有 UI 操作都必须在主线程的队列上执行。您可以通过检查以下内容来向自己证明您在错误的线程上:

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

ADDENDUM

附录

If there's any chance selfmight 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(...)

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

ADDENDUM 2

附录 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:

请注意,来自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.

NSOperation 与 Grand Central Dispatch (GCD)

GCD [dispatch_* 调用] 是一种表示将要并发执行的工作单元的轻量级方式。

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

ADDENDUM 3

附录 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.

笔记

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

SWIFT 4

快速 4

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

Reference:

参考:

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

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

回答by Mette

I've got the same problem with login issue. probably we do the same tutorial. After naming your segue identifier you need to replace:

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

performSegueWithIdentifier("Klikur", sender: self)

with:

和:

dispatch_async(dispatch_get_main_queue()){

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

}

type of seque needs to be set as "show (e.g. Push)" in the storyboard segue. Hope it will work.

序列的类型需要在故事板序列中设置为“显示(例如推送)”。希望它会起作用。

回答by GregJaskiewicz

Make sure you're putting your: self.performSegue(withIdentifier: ..., ...)

确保你把你的: self.performSegue(withIdentifier: ..., ...)

in viewDidAppear or later. It won't work in viewWillAppear or viewDidLoad.

在 viewDidAppear 或更高版本中。它不适用于 viewWillAppear 或 viewDidLoad。

回答by NRitH

The segue identifier that you pass to performSegueWithIdentifier(_:sender:)must exactlymatch the ID you've given the segue in the storyboard. I assume that you have a segue between the login view controller and the success view controller, which is as it should be; if not, ctrl+drag from the first to the second view controller, then select the segue's icon in the storyboard and set its ID to Klikur. Don'tperform the navigation on the button click, as one commenter said, because that defeats the main purpose of having segues, which is to give a visualindication of the application flow in the storyboard.

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

EDIT: Here's the code for a 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.
        }
    }

}

And a screenshot of the segue properties that I'm talking about: enter image description here

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

回答by Felecia Genet

swift 3.x

快速 3.x

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

回答by ibk

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

回答by Ppillo

An example in a login. When you have success in your login after clicking a button (Action) you can use:

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

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

But if you are launching the app and you got the credentials from your keychain you need to use this as a part of the theard:

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

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

回答by Justin Domnitz

Check to make sure you are running the perform segue on a visible view controller.

检查以确保您在可见视图控制器上运行执行转场。

This is an edge case, but my perform segue failed when I attempted to run it on the view controller belonging to my UIPageViewController that was not currently visible. It also failed if I attempted to do the segue on all view controllers belonging to my UIPageViewController, including the view controller currently visible. The fix was to track which view controller was currently visible in my UIPageViewController, and only perform the segue on that view controller.

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