我正在创建一个使用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???
        }
    }
}

我正在使用上面的类方法来检查会话状态的变化,它工作得很好。

问:一旦我有了用户的数据,我如何从这个自定义类中segue到下一个视图?

我在storyboard上有一个带标识符的segue,我试图找到一种方法从一个不是视图控制器的类执行segue


当前回答

你可以使用performSegueWithIdentifier函数来做这件事。

语法:

func performSegueWithIdentifier(identifier: String, sender: AnyObject?)

例子:

 performSegueWithIdentifier("homeScreenVC", sender: nil)

其他回答

对于单元测试来说,您想要做的事情非常重要。基本上你需要在视图控制器中创建一个小的本地函数。给函数起任何名字,只要包括performseguewithidentifier。

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: segue到下一个视图??,写一些类似的东西:

self.yourFunction()

在你的单元测试中,你可以简单地调用它:

let f = UtilClass()
f.doThatThing()

doThatThing是你的fbsessionstatechange UtilClass是FBManager。

对于您的实际代码,只需将localFunc(没有括号)传递给FBManager类。

你可以像这样使用segue:

self.performSegueWithIdentifier("push", sender: self)
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
    if segue.identifier == "push" {

    }
}

另一个选择是使用模态segue

步骤1:转到故事板,给视图控制器一个故事板ID。您可以在右侧的标识检查器中找到更改故事板ID的位置。 让我们调用故事板ID ModalViewController

第二步:打开'sender'视图控制器(让我们称它为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)
    }
  }
}

注意,我们要打开的视图控制器也叫做ModalViewController

步骤3:关闭ModalViewController,添加这个

public class ModalViewController {
   @IBAction func closeThisViewController(_ sender: Any?) {
      self.presentingViewController?.dismiss(animated: true, completion: 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 ID检查器中设置“IdentifierOfDestinationVC”

performSegue(withIdentifier: "IdentifierOfDestinationVC", sender: 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)
        }


    }