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>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 不起作用的主要内容,如果未能解决你的问题,请参考以下文章