快速转场不起作用?
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 也有同样的问题。
示例: 让我们拿两个故事板 main 和 signup。
1) 在main.storyboard
创建一个故事板引用。将 Storyboard Reference 中的storyboardId
设置为signup
,将referencedId
设置为signup.storyboard
中的场景(viewController) 的storyboardId
。看这个链接看清楚图片Storyboard to Storyboard
2) 在main.storyboard
中设置viewController
和Storyboard 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)
【讨论】:
以上是关于快速转场不起作用?的主要内容,如果未能解决你的问题,请参考以下文章