How to push and present to UIViewController programmatically without segue in iOS Swift 3 How to push and present to UIViewController programmatically without segue in iOS Swift 3 xcode xcode

How to push and present to UIViewController programmatically without segue in iOS Swift 3


Push

do like

let storyboard = UIStoryboard(name: "Main", bundle: nil)let vc = storyboard.instantiateViewControllerWithIdentifier("NewsDetailsVCID") as NewsDetailsViewController  vc.newsObj = newsObj navigationController?.pushViewController(vc, animated: true)

or safer

  if let viewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "NewsDetailsVCID") as? NewsDetailsViewController {        viewController.newsObj = newsObj        if let navigator = navigationController {            navigator.pushViewController(viewController, animated: true)        }    }

present

   let storyboard = UIStoryboard(name: "Main", bundle: nil)   let vc = self.storyboard?.instantiateViewControllerWithIdentifier("NewsDetailsVCID") as! NewsDetailsViewController      vc.newsObj = newsObj           present(vc!, animated: true, completion: nil)  

or safer

   if let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "NewsDetailsVCID") as? NewsDetailsViewController     {     vc.newsObj = newsObj    present(vc, animated: true, completion: nil)    }


With an elegant way.

Create an Navigatable protocol:

protocol Navigatable {    /// Storyboard name where this view controller exists.    static var storyboardName: String { get }    /// Storyboard Id of this view controller.    static var storyboardId: String { get }    /// Returns a new instance created from Storyboard identifiers.    static func instantiateFromStoryboard() -> Self}

Create a default instantiate controller implementation:

/** Extension of Navigatable protocol with default implementations. */extension Navigatable {    static func instantiateFromStoryboard() -> Self {        let storyboard = UIStoryboard(name: self.storyboardName, bundle: nil)        guard            let viewController = storyboard                .instantiateViewController(withIdentifier: self.storyboardId) as? Self else {                    fatalError("Cannot instantiate the controller.")        }        return viewController    }}

Extends the UIViewController to push a view controller:

extension UIViewController {    /**     Pushes a view controller of the provided type.     - Parameter viewControllerType: Type of view controller to push.     - Parameter completion: Function to be executed on completion.     Contains the view controller that was pushed when successful and nil otherwise.     */    func pushViewControllerOfType<T: Navigatable>(viewControllerType: T.Type, completion: (T) -> Void) {        let viewController = T.instantiateFromStoryboard()        if let vc = viewController as? UIViewController {            self.pushViewController(vc, animated: true)        }        completion(viewController)    }    /**     Pushes a view controller of the provided type.     - Parameter viewControllerType: Type of view controller to push.     */    func pushViewControllerOfType<T: Navigatable>(viewControllerType: T.Type) {        self.pushViewControllerOfType(viewControllerType: viewControllerType) { _ in }    }}

Then you can use the Navigatable protocol for a specific view controller.

class MySuperViewController {   override func viewDidLoad() {      ...   }   // ...}extension MySuperViewController: Navigatable {    static var storyboardName: String {        return "Main"    }    static var storyboardId: String {        return "MySuperViewControllerId" // From your story board name Main    }}// Instantiate your controllerlet vc = MySuperViewController.instantiateFromStoryboard()// Or//// Push your view controller// testViewController.swiftself.pushViewControllerOfType(viewControllerType: MySuperViewController)


//Create object of view controller let obj = self.storyboard?.instantiateViewController(withIdentifier: "ViewControllerIdentifier”) as! ViewControllerName//Push Controllerself.navigationController?.pushViewController(obj, animated: true)//Present Controllerself.navigationController?.present(obj, animated: true, completion: nil)