Swift performSegueWithIdentifier 不起作用

Posted

技术标签:

【中文标题】Swift performSegueWithIdentifier 不起作用【英文标题】:Swift performSegueWithIdentifier not working 【发布时间】:2015-08-30 02:29:12 【问题描述】:

我正在尝试在用户成功登录其帐户后切换视图控制器,但它无法正常工作。我不能直接使用 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 设置为“测试”,并且在输入正确信息时它不会切换视图控制器。有人可以帮我解决我的问题吗?

【问题讨论】:

移除 segue 并在按钮点击事件上执行导航。 该代码在功能 buttonTapped 所以它应该转换,但它不是。 您是否从情节提要中删除了转场? 是的,没有 segue 将登录链接到 sucessfulLoginPage 嘿,我在调试我拥有的 Segue 时发现了这样的问题:po self.perform(NSSelectorFromString("storyboardSegueTemplates"))。另外,我发现了问题,在以前的 UIViewController 通过代码而不是 performSegue 添加到 UINavigationStack 之后没有 segues :)),我通过 performSegue 为以前的控制器修复它 :) 【参考方案1】:

[假设您的代码没有崩溃,而只是无法继续]

至少有一个问题是:

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 可能变为 nil,例如因为不需要而被解雇或以其他方式释放,您应该将 self 弱捕获为 [weak self] 而不是 unowned,并使用安全展开:if let s = self s.doStuff() 或可选链接:self?.doStuff(...)

附录 2

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

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

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

NSOperation 与 Grand Central Dispatch (GCD)

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

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

附录 3

苹果在这里隐藏了单线程规则:

注意

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

SWIFT 4

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

参考:

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

【讨论】:

除非您在此处准确重现崩溃消息,否则没有帮助。 2015-08-29 22:07:26.879 ParseStarterProject-Swift[6339:925415] *** 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“接收方(<0x7fd6f048d7e0> 【参考方案2】:

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

在 viewDidAppear 或更高版本中。它在 viewWillAppear 或 viewDidLoad 中不起作用。

【讨论】:

另外,不要忘记将视图与视图控制器类链接起来,就像我刚刚做的那样。【参考方案3】:

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

performSegueWithIdentifier("Klikur", sender: self)

与:

dispatch_async(dispatch_get_main_queue())

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


需要在storyboard segue中将sequ的类型设置为“show (e.g. Push)”。 希望它会起作用。

【讨论】:

【参考方案4】:

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

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

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 属性的屏幕截图:

【讨论】:

你能贴出故事板中视图控制器和segue的截图,以及segue的属性面板吗? 它们已被添加。 第二个屏幕截图中的属性用于名为“Klikur”的视图控制器。我需要查看 ID 为“Klikur”的 segue。在情节提要中将您的视图控制器隔开一点,您会看到转场。从你的登录场景到你的成功场景应该有一个,它的ID应该是“Klikur”。【参考方案5】:

swift 3.x

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

【讨论】:

【参考方案6】:
DispatchQueue.main.async() 
    self.performSegue(withIdentifier: "GoToHomeFromSplash", sender: self)`  

【讨论】:

在你的代码中添加一些 cmets,让人们理解你想要传达的内容。【参考方案7】:

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

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

【讨论】:

【参考方案8】:

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

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

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

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

【讨论】:

以上是关于Swift performSegueWithIdentifier 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Swift入门系列--Swift官方文档(2.2)--中文翻译--About Swift 关于Swift

swift 示例BS swift.swift

swift swift_bug.swift

ios 整理(一)swift和oc的区别

swift swift_extension5.swift

swift swift_optional4.swift