快速转场不起作用?

Posted

技术标签:

【中文标题】快速转场不起作用?【英文标题】:Swift segue not working? 【发布时间】:2016-03-12 02:24:25 【问题描述】:

我的 Swift segue 根本不工作,也没有抛出任何错误。断点显示应用程序位于该行但没有任何反应:

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

代码块是 Facebook 的登录表单:

if let accessToken: FBSDKAccessToken = FBSDKAccessToken.currentAccessToken() 
    PFFacebookUtils.logInInBackgroundWithAccessToken(result.token, block: 
        (user: PFUser ? , error : NSError ? ) - > Void in
        if user!.isNew 
            self.performSegueWithIdentifier("SignupSegue", sender: self)
         else 
            self.navigateToInGame(true)
        
    )

这是它应该调用的 segue 函数,但甚至没有得到它:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
    
        if (segue.identifier == "SignupSegue") 
            let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
            let vc = storyboard.instantiateViewControllerWithIdentifier("SignUpViewController") 
            self.showViewController(vc, sender: self)
        
    

有什么想法吗?

【问题讨论】:

我只是想弄清楚为什么在故事板中设置 segue 后需要显示 viewController?您可能不会使用标识符“SignupSegue”设置 segue。所以请仔细检查一下。有错请指正。 好的,我明白了。我注释掉了“showViewController”行(我从谷歌搜索中得到了这个)。我只是想建立一个从一个故事板到另一个故事板的转场。将其注释掉后仍然出现错误。谢谢! 【参考方案1】:

通常,任何 UI 更新都必须在主线程中进行。我认为PFFacebookUtils.logInInBackgroundWithAccessToken 的块在上述情况下仍处于后台状态。也许触发dispatch_async(dispatch_get_main_queue(), )中的showViewController,看看有什么不同。

dispatch_async(dispatch_get_main_queue(), 
    let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
    let vc = storyboard.instantiateViewControllerWithIdentifier("SignUpViewController")
    self.showViewController(vc, sender: self)
)

【讨论】:

派送绝对有帮助!我现在收到一个错误LoginViewController has no segue with identifier 'SignupSegue。当我没有在情节提要中绘制转场时,我通常会看到此错误。然而,由于它们是独立的故事板,我希望if identifier 函数能够以编程方式执行此操作。我错过了什么吗? @james 如果我理解你有一个单独的故事板的意思,听起来你有一个不同名称但不是“主要”的故事板,对吧? UIStoryboard(name: "SomethingElse", bundle: nil) 对不起。我有 Main.storyboard 和 Login.storyboard。我想继续 LoginViewController (Login.storyboard) -> SignUpViewController (Main.storyboard) 我设置了ID,但它不起作用。错误说它找不到 segue,所以我认为 Storyboard ID 设置正确。我很困惑为什么即使我在函数中设置它也找不到segue:/ @james 嗯,应该很简单。我刚刚创建了一个示例项目,您可以在此处下载并作为参考。 db.tt/LLPH8Kvh【参考方案2】:

好的。我刚试了一下。希望您完成了有关 StoryBoard Reference 的所有事情。 我的 performSegueWithIdentifier 也有同样的问题。

示例: 让我们拿两个故事板 mainsignup

1) 在main.storyboard 创建一个故事板引用。将 Storyboard Reference 中的storyboardId 设置为signup,将referencedId 设置为signup.storyboard 中的场景(viewController) 的storyboardId。看这个链接看清楚图片Storyboard to Storyboard

2) 在main.storyboard 中设置viewControllerStoryboard Reference 之间的segue 标识符

3) 由于performSegueWithIdentifier 遇到同样的问题,我将其替换为shouldPerformSegueWithIdentifier

override func shouldPerformSegueWithIdentifier(identifier: String, sender: AnyObject?) -> Bool 
    if(identifier == "segue_identifier")
       // segue_identifier is the viewController and storyBoard Reference segue identifier.
        print("hello")
    
    return true;

如果您发现任何问题,请告诉我。它确实对我有用。

【讨论】:

【参考方案3】:

执行 segue 会导致呈现一个新的视图控制器。您不需要也不能在 prepareForSegue 中创建和显示视图控制器。它看起来像:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
    
        if (segue.identifier == "SignupSegue") 

            let vc = segue.destinationViewController

        
    

【讨论】:

感谢您的回复!如果我想在不同的故事板中切换到另一个控制器,这会起作用吗? @james 您可以使用故事板参考(在 ios 8 及更高版本中可用)。否则你不能在故事板之间使用 segue。 哦,好的...我想知道我是否应该将主故事板上的所有内容组合起来 @james 不要这样做,我试过了,但是当你打开故事板文件时 Xcode 会变得非常非常慢(花了我 3 分钟)。 只是为了试一试,我将 LoginViewController 移到了 Main storyboard。即使两个控制器在同一个 segue 中,self.performSegueWithIdentifier("SignupSegue", sender: self) 仍然会产生错误 LoginViewController has no segue with identifier 'SignupSegue'' 所以很困惑【参考方案4】:

Swift 3 解决了:

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) 
            if (segue.identifier == "SignupSegue") 
                DispatchQueue.main.async 
                    let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
                    let vc = storyboard.instantiateViewController(withIdentifier: "SignUpViewController")
                    self.show(vc, sender: self) 
                
          
    

【讨论】:

【参考方案5】:

你可以试试这个……

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
    
    if (segue.identifier == "SignupSegue") 
        if let destination = segue.destination as? SignUpViewController 
         ...
        

    

【讨论】:

请编辑您的答案以解释为什么这段代码回答了这个问题。 因为我认为这些都不需要。 --> let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil) let vc = storyboard.instantiateViewControllerWithIdentifier("SignUpViewController")【参考方案6】:

我可以为自己解决同样问题的最接近的方法:

使用类中的初始化值触发 var segueLogin : Bool = false

当 PFFacebookUtils 获得 segue 所需的值时,将触发器更改为 true:

PFFacebookUtils.logInInBackground(withReadPermissions: permissions) 
            (user: PFUser?, error: Error?) -> Void in
            if let user = user 
                if user.isNew 
                    print("User signed up and logged in through Facebook!")
                    self.segueLogin = true

                 else 
                    print("User logged in through Facebook!")
                    self.segueLogin = true
                
             else 
                print("Uh oh. The user cancelled the Facebook login.")
                self.loginCancelledLabel.alpha = 1
            
        

然后将代码添加到 viewDidAppear 类。意识到它每次 PFFacebookUtils 完成时都会启动。所以它会检查返回值是否为真,并在 PFFacebookUtils 会话成功后执行 segue:

override func viewDidAppear(_ animated: Bool) 
        if segueLogin == true 
            self.performSegue(withIdentifier: "segueSingup", sender: self)
        
    

【讨论】:

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

以编程方式继续不起作用

摇动手势不起作用

如果应用程序进入后台,UIView 动画将不起作用

快速无效计时器不起作用

快速护照会话不起作用

插入排序的快速排序代码不起作用