[ios] IOS - How to segue programmatically using swift

I'm creating an app that uses the Facebook SDK to authenticate users. I'm trying to consolidate the facebook logic in a separate class. Here is the code (stripped for simplicity):

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???
        }
    }
}

I'm using the above class method to check session state changes, and it works fine.

Q: Once I have the user's data, how can I segue to the next view from within this custom class?

EDIT: just to be clear, I have a segue with identifier on the storyboard, and I'm trying to find a way to perform a segue from a class which is not the view controller

This question is related to ios iphone facebook swift segue

The answer is


You can do this thing using performSegueWithIdentifier function.

Screenshot

Syntax :

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

Example :

 performSegueWithIdentifier("homeScreenVC", sender: nil)

If your segue exists in the storyboard with a segue identifier between your two views, you can just call it programmatically using:

performSegue(withIdentifier: "mySegueID", sender: nil)

For older versions:

performSegueWithIdentifier("mySegueID", sender: nil)

You could also do:

presentViewController(nextViewController, animated: true, completion: nil)

Or if you are in a Navigation controller:

self.navigationController?.pushViewController(nextViewController, animated: true)

What you want to do is really important for unit testing. Basically you need to create a small local function in the view controller. Name the function anything, just include the performSegueWithIndentifier.

func localFunc() {
    println("we asked you to do it")
    performSegueWithIdentifier("doIt", sender: self)
}

Next change your utility class FBManager to include an initializer that takes an argument of a function and a variable to hold the ViewController's function that performs the segue.

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")
    }
}

(The convenience init allows you to use this in unit testing without executing the segue.)

Finally, where you have //todo: segue to the next view???, put something along the lines of:

self.yourFunction()

In your unit tests, you can simply invoke it as:

let f = UtilClass()
f.doThatThing()

where doThatThing is your fbsessionstatechange and UtilClass is FBManager.

For your actual code, just pass localFunc (no parenthesis) to the FBManager class.


This worked for me.

First of all give the view controller in your storyboard a Storyboard ID inside the identity inspector. Then use the following example code (ensuring the class, storyboard name and story board ID match those that you are using):

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)

For more details see http://sketchytech.blogspot.com/2012/11/instantiate-view-controller-using.html best wishes


Another option is to use modal segue

STEP 1: Go to the storyboard, and give the View Controller a Storyboard ID. You can find where to change the storyboard ID in the Identity Inspector on the right. Lets call the storyboard ID ModalViewController

STEP 2: Open up the 'sender' view controller (let's call it ViewController) and add this code to it

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)
    }
  }
}

Note that the View Controller we want to open is also called ModalViewController

STEP 3: To close ModalViewController, add this to it

public class ModalViewController {
   @IBAction func closeThisViewController(_ sender: Any?) {
      self.presentingViewController?.dismiss(animated: true, completion: nil)
   }
}

Swift 3 - Also works with SpriteKit

You can use NSNotification.

Example:

1.) Create a segue in the storyboard and name the identifier "segue"

2.) Create a function in the ViewController you are segueing from.

func goToDifferentView() {

    self.performSegue(withIdentifier: "segue", sender: self)

}

3.) In the ViewDidLoad() of your ViewController you are segueing from create the observer.

NotificationCenter.default.addObserver(self, selector: #selector(goToDifferentView), name: "segue" as NSNotification.Name, object: nil)

Update - Last time I used this I had to change the .addObserver call to the following code to silence the errors.

NotificationCenter.default.addObserver(self, selector: #selector(goToDifferentView), name: NSNotification.Name(rawValue: "segue"), object: nil)

4.) In the ViewController or Scene you are segueing to, add the Post Method wherever you want the segue to be triggered.

NotificationCenter.default.post(name: "segue" as NSNotification.Name, object: nil)

Update - Last time I used this I had to change the .post call to the following code to silence the errors.

NotificationCenter.default.post(NSNotification(name: NSNotification.Name(rawValue: "segue"), object: nil) as Notification)

You can use segue like this:

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

    }
}

You can use NSNotification

Add a post method in your custom class:

NSNotificationCenter.defaultCenter().postNotificationName("NotificationIdentifier", object: nil)

Add an observer in your ViewController:

NSNotificationCenter.defaultCenter().addObserver(self, selector: "methodOFReceivedNotication:", name:"NotificationIdentifier", object: nil)

Add function in you ViewController:

func methodOFReceivedNotication(notification: NSNotification){
    self.performSegueWithIdentifier("yourIdentifierInStoryboard", sender: self)
}

This worked for me:

//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)
        }


    }

If your segue exists in the storyboard with a segue identifier between your two views, you can just call it programmatically using

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

If you are in Navigation controller

let viewController = YourViewController(nibName: "YourViewController", bundle: nil)        
self.navigationController?.pushViewController(viewController, animated: true)

I will recommend you for second approach using navigation controller.


Examples related to ios

Adding a UISegmentedControl to UITableView Crop image to specified size and picture location Undefined Symbols error when integrating Apptentive iOS SDK via Cocoapods Keep placeholder text in UITextField on input in IOS Accessing AppDelegate from framework? Autoresize View When SubViews are Added Warp \ bend effect on a UIView? Speech input for visually impaired users without the need to tap the screen make UITableViewCell selectable only while editing Xcode 12, building for iOS Simulator, but linking in object file built for iOS, for architecture arm64

Examples related to iphone

Detect if the device is iPhone X Xcode 8 shows error that provisioning profile doesn't include signing certificate Access files in /var/mobile/Containers/Data/Application without jailbreaking iPhone Certificate has either expired or has been revoked Missing Compliance in Status when I add built for internal testing in Test Flight.How to solve? cordova run with ios error .. Error code 65 for command: xcodebuild with args: "Could not find Developer Disk Image" Reason: no suitable image found iPad Multitasking support requires these orientations How to insert new cell into UITableView in Swift

Examples related to facebook

I am receiving warning in Facebook Application using PHP SDK React-Native: Application has not been registered error Can't Load URL: The domain of this URL isn't included in the app's domains Facebook OAuth "The domain of this URL isn't included in the app's domain" Facebook login message: "URL Blocked: This redirect failed because the redirect URI is not whitelisted in the app’s Client OAuth Settings." Warning: Each child in an array or iterator should have a unique "key" prop. Check the render method of `ListView` Open Facebook Page in Facebook App (if installed) on Android App not setup: This app is still in development mode IOS - How to segue programmatically using swift Get ALL User Friends Using Facebook Graph API - Android

Examples related to swift

Make a VStack fill the width of the screen in SwiftUI Xcode 10.2.1 Command PhaseScriptExecution failed with a nonzero exit code Command CompileSwift failed with a nonzero exit code in Xcode 10 Convert Json string to Json object in Swift 4 iOS Swift - Get the Current Local Time and Date Timestamp Xcode 9 Swift Language Version (SWIFT_VERSION) How do I use Safe Area Layout programmatically? How can I use String substring in Swift 4? 'substring(to:)' is deprecated: Please use String slicing subscript with a 'partial range from' operator Safe Area of Xcode 9 The use of Swift 3 @objc inference in Swift 4 mode is deprecated?

Examples related to segue

Programmatically go back to previous ViewController in Swift IOS - How to segue programmatically using swift What's the difference between all the Selection Segues? How to perform Unwind segue programmatically? Creating a segue programmatically Perform Segue programmatically and pass parameters to the destination view