我正在创建一个使用 Facebook SDK 对用户进行身份验证的应用程序。我正在尝试将 facebook 逻辑合并到一个单独的类中。这是代码(为简单起见,已删除):
import Foundation
class FBManager {
class func fbSessionStateChane(fbSession:FBSession!, fbSessionState:FBSessionState, error:NSError?){
//... handling all session states
FBRequestConnection.startForMeWithCompletionHandler { (conn: FBRequestConnection!, result: AnyObject!, error: NSError!) -> Void in
println("Logged in user: \n\(result)");
let storyboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
let loggedInView: UserViewController = storyboard.instantiateViewControllerWithIdentifier("loggedInView") as UserViewController
loggedInView.result = result;
//todo: segue to the next view???
}
}
}
我正在使用上面的类方法来检查会话状态的变化,它工作正常。
问:获得用户数据后,如何从这个自定义类中转到下一个视图?
为了清楚起见,我在情节提要上有一个带有标识符的转场,我正在尝试找到一种方法来从不是视图控制器的类中执行转场
performSegue:
?
如果您的 segue 存在于情节提要中,并且您的两个视图之间有一个 segue 标识符,您可以使用以下方式以编程方式调用它:
performSegue(withIdentifier: "mySegueID", sender: nil)
对于旧版本:
performSegueWithIdentifier("mySegueID", sender: nil)
你也可以这样做:
presentViewController(nextViewController, animated: true, completion: nil)
或者,如果您在导航控制器中:
self.navigationController?.pushViewController(nextViewController, animated: true)
如果您的 segue 存在于情节提要中,并且您的两个视图之间有一个 segue 标识符,您可以使用以编程方式调用它
self.performSegueWithIdentifier("yourIdentifierInStoryboard", sender: self)
如果您在导航控制器中
let viewController = YourViewController(nibName: "YourViewController", bundle: nil)
self.navigationController?.pushViewController(viewController, animated: true)
我会推荐你使用导航控制器的第二种方法。
您可以使用 NSNotification
在您的自定义类中添加一个 post 方法:
NSNotificationCenter.defaultCenter().postNotificationName("NotificationIdentifier", object: nil)
在你的 ViewController 中添加一个观察者:
NSNotificationCenter.defaultCenter().addObserver(self, selector: "methodOFReceivedNotication:", name:"NotificationIdentifier", object: nil)
在 ViewController 中添加功能:
func methodOFReceivedNotication(notification: NSNotification){
self.performSegueWithIdentifier("yourIdentifierInStoryboard", sender: self)
}
你可以像这样使用segue:
self.performSegueWithIdentifier("push", sender: self)
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
if segue.identifier == "push" {
}
}
Swift 3 - 也适用于 SpriteKit
您可以使用 NSNotification。
例子:
1.) 在情节提要中创建一个 segue,并将标识符命名为“segue”
2.) 在您要从中选择的 ViewController 中创建一个函数。
func goToDifferentView() {
self.performSegue(withIdentifier: "segue", sender: self)
}
3.) 在 ViewController 的 ViewDidLoad() 中,您正在创建观察者。
NotificationCenter.default.addObserver(self, selector: #selector(goToDifferentView), name: "segue" as NSNotification.Name, object: nil)
更新 - 上次我使用它时,我不得不将 .addObserver
调用更改为以下代码以消除错误。
NotificationCenter.default.addObserver(self, selector: #selector(goToDifferentView), name: NSNotification.Name(rawValue: "segue"), object: nil)
4.) 在您要转场的 ViewController 或场景中,在您希望触发转场的任何位置添加 Post 方法。
NotificationCenter.default.post(name: "segue" as NSNotification.Name, object: nil)
更新 - 上次我使用它时,我不得不将 .post
调用更改为以下代码以消除错误。
NotificationCenter.default.post(NSNotification(name: NSNotification.Name(rawValue: "segue"), object: nil) as Notification)
NotificationCenter.default.addObserver(self, selector: #selector(goToDifferentView), name: NSNotification.Name(rawValue: "segue"), object: nil)
上面已经有了很好的答案,我不想在执行 segue 之前把重点放在准备工作上。
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.destination is YourDestinationVC {
let vc = segue.destination as? YourDestinationVC
// "label" and "friends" are part of destinationVC
vc?.label = "someText"
vc?.friends = ["John","Mike","Garry"]
}
一旦你完成了你想要传递给你的destinationVC的数据,然后在适当的地方执行你的segue。您可以在 StoryBoard ID 字段的 StoryBoard Identity 检查器中设置“IdentifierOfDestinationVC”
performSegue(withIdentifier: "IdentifierOfDestinationVC", sender: nil)
您想做的事情对于单元测试非常重要。基本上你需要在视图控制器中创建一个小的本地函数。将函数命名为任何名称,只需包含 performSegueWithIndentifier
。
func localFunc() {
println("we asked you to do it")
performSegueWithIdentifier("doIt", sender: self)
}
接下来更改您的实用程序类 FBManager
以包含一个初始化程序,该初始化程序接受一个函数的参数和一个变量来保存执行 segue 的 ViewController 函数。
public class UtilClass {
var yourFunction : () -> ()
init (someFunction: () -> ()) {
self.yourFunction = someFunction
println("initialized UtilClass")
}
public convenience init() {
func dummyLog () -> () {
println("no action passed")
}
self.init(dummyLog)
}
public func doThatThing() -> () {
// the facebook login function
println("now execute passed function")
self.yourFunction()
println("did that thing")
}
}
(方便的 init 允许您在不执行 segue 的情况下在单元测试中使用它。)
最后,在你有 //todo: 的地方继续下一个视图???
self.yourFunction()
在您的单元测试中,您可以简单地调用它:
let f = UtilClass()
f.doThatThing()
其中 doThatThing 是您的 fbsessionstatechange,UtilClass
是 FBManager。
对于您的实际代码,只需将 localFunc
(无括号)传递给 FBManager 类。
这对我有用。
首先,在身份检查器中为情节提要中的视图控制器提供情节提要 ID。然后使用以下示例代码(确保类、故事板名称和故事板 ID 与您正在使用的匹配):
let viewController:
UIViewController = UIStoryboard(
name: "Main", bundle: nil
).instantiateViewControllerWithIdentifier("ViewController") as UIViewController
// .instantiatViewControllerWithIdentifier() returns AnyObject!
// this must be downcast to utilize it
self.presentViewController(viewController, animated: false, completion: nil)
有关更多详细信息,请参阅 http://sketchytech.blogspot.com/2012/11/instantiate-view-controller-using.html 最良好的祝愿
您可以使用 performSegueWithIdentifier
函数来执行此操作。
https://i.stack.imgur.com/31nGG.png
句法 :
func performSegueWithIdentifier(identifier: String, sender: AnyObject?)
例子 :
performSegueWithIdentifier("homeScreenVC", sender: nil)
另一种选择是使用模态segue
第 1 步:转到情节提要,并为视图控制器提供一个情节提要 ID。您可以在右侧的 Identity Inspector 中找到更改情节提要 ID 的位置。让我们调用情节提要 ID ModalViewController
第 2 步: 打开“发送者”视图控制器(我们称之为 ViewController
)并将此代码添加到其中
public class ViewController {
override func viewDidLoad() {
showModalView()
}
func showModalView() {
if let mvc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ModalViewController") as? ModalViewController {
self.present(mvc, animated: true, completion: nil)
}
}
}
注意我们要打开的 View Controller 也叫 ModalViewController
第 3 步:要关闭 ModalViewController,请将其添加到其中
public class ModalViewController {
@IBAction func closeThisViewController(_ sender: Any?) {
self.presentingViewController?.dismiss(animated: true, completion: nil)
}
}
这对我有用:
//Button method example
@IBAction func LogOutPressed(_ sender: UIBarButtonItem) {
do {
try Auth.auth().signOut()
navigationController?.popToRootViewController(animated: true)
} catch let signOutError as NSError {
print ("Error signing out: %@", signOutError)
}
}