How can I programmatically present a view controller modally? - ios

Edit: When solving this problem, I found that it is much easier to start with your UITabBarController, then perform login validation via your AppDelegate.m's didFinishLaunchingWithOptions: method.
Question:
This code is in the the application didFinishLaunchingWithOptions: method in my AppDelegate.m
if([result isEqualToString: #"log"])
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *ivc = [storyboard instantiateViewControllerWithIdentifier:#"TabBarControl"];
[(UINavigationController*)self.window.rootViewController pushViewController:ivc animated:NO];
NSLog(#"It's hitting log");
}
It simply takes an HTTP response for the user being logged in, and takes them to my TabBarController. The problem is that it's using a push rather than a modal transition to display the page. Since presentModalViewController method is deprecated or deleted in iOS7, how can I programmatically force a modal presentation?
EDIT:
)

Swift
This is how you would do it in Swift without referencing the navigation controller:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let secondViewController = storyboard.instantiateViewController(withIdentifier: "secondViewController") as! SecondViewController
self.present(secondViewController, animated: true, completion: nil)
Change the storyboard name, view controller, and id as needed.
See also how to dismiss a view controller programmatically.

In swift 4.2 you can do it like this. For those who want this answer in swift updated version.
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "ExampleViewController")
self.present(controller, animated: true, completion: nil)

In Swift 3/4
let storyB = UIStoryboard(name: "Main", bundle: nil)
let secondViewController = storyB.instantiateViewController(withIdentifier: "SecondViewControllerID") as! SecondViewController
self.present(secondViewController, animated: true, completion: nil)

let storyB = UIStoryboard(name: "Main", bundle: nil)
let secondViewController =
storyB.instantiateViewController(withIdentifier:
"SecondViewControllerID") as! SecondViewController
self.present(secondViewController, animated: true, completion: nil)
In the secondViewController use this code to go back.
self.dismiss(animated: true, completion: nil)

Related

Present and dismiss view modally in tabbed application using swift

I've created a tabbed application and am able to present a view modally using the code below, however, I'm stuck on dismissing the view and displaying the tab bar and first view controller.
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let signUpViewController = storyboard.instantiateViewController(withIdentifier:"SignUpViewController") as! SignUpViewController
self.window?.makeKeyAndVisible()
self.window?.rootViewController = signUpViewController
Inside that signUpViewController do this after giving that tabBarController a storyboard identifier in IB
let tab = storyboard!.instantiateViewController(withIdentifier:"tab")
UIApplication.shared.keyWindow?.rootViewController = tab
OR
(UIApplication.shared.delegate as! AppDelegate).window?.rootViewController = tab
You should present your modal vc over you tab bar vc
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let signUpViewController = storyboard.instantiateViewController(withIdentifier:"SignUpViewController") as! SignUpViewController
signUpViewController.modalPresentationStyle = UIModalPresentationStyle.fullScreen
signUpViewController.modalTransitionStyle = UIModalTransitionStyle.coverVertical
self.window.rootViewController.present(myModalViewController, animated: true, completion: nil)
(if self.window.rootViewController - your tab bar view controller)
And in this case you can use dismiss(animated: true, completion: nil) method in modal vc to dismiss it.
In your TabBarViewController, do the following when presenting SignUpViewController
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let viewController = storyboard.instantiateViewController(withIdentifier:"SignUpViewController")
viewController.modalPresentationStyle = .overFullScreen
self.presentViewController(viewController, animated:true)
and when dismissing, simply call the dismiss code from SignUpViewController
e.g. dismissViewControllerAnimated

Navigation item disappears with popover

I have created a popup displaying a list in which I send the text to another viewcontroller, but when I close the popup, the Navigation Item disappears, and I have already searched for nothing to solve this problem. The code that sends the selected list item in the popover is this:
Shared.shared.filialNome = self.filiais[indexPath.row].razaoSocial
self.recebeCodigo = self.filiais[indexPath.row].codigo
Shared.shared.codigoFilial = self.recebeCodigo
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let newViewController = storyBoard.instantiateViewController(withIdentifier: "AniversarioViewController") as! AniversarioViewController
self.present(newViewController, animated: true, completion: nil)
Type of following = Modal
I have tried to call Present as Popover but the error persists, it seems that it does not close the VC completely, somebody can help me.
Before opening the popover and
After opening the popover
It seems like, as you are presenting the view controller (and ViewControllers do not have navigation item until we embed it in navigation controller).
So you can embed the same ViewController in navigation controller in storyboard and then get the reference for that navigation controller and present the navigation controller like
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let navController = storyBoard.instantiateViewController(withIdentifier: "YourNavigationControllerIdentifier") as! UINavigationController
self.present(navController, animated: true, completion: nil)
Or if you don't want to embed you can do programmatically like
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let newViewController = storyBoard.instantiateViewController(withIdentifier: "AniversarioViewController") as! AniversarioViewController
let navController = UINavigationController.init(rootViewController: newViewController)
self.present(navController, animated: true, completion: nil)

Swift: Prevent flicker when presenting login screen at startup

We have two storyboards in our app. The default view in storyboard #1 assumes the user has previously supplied valid credentials. If they have not done so we "redirect" to the login screen in storyboard #2:
let storyboard = UIStoryboard(name: "Authentication", bundle: nil)
let controller = storyboard.instantiateViewControllerWithIdentifier("LoginController") as UIViewController
presentViewController(controller, animated: true, completion: nil)
This works - but there is a flicker when this code runs where the default view briefly appears prior to the login view being displayed. How can you perform this action without a flicker?
Instead of presenting LoginController you have to set the respective ViewController as rootviewcontroller to the window in Appdelegate itself as folllows:
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
//Check for credentials,if value available make LoginStatus as true
if LoginStatus == true{
//Change Storyboard name "Main" to your "storyboard #1" name.
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
//Change Viecontroller name "My_Offer" to your "DefaultViewController name" name.
let vc = mainStoryboard.instantiateViewControllerWithIdentifier("My_Offer") as UIViewController
let navigationController = UINavigationController(rootViewController: vc)
self.window!.rootViewController = navigationController
}else{
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Authentication", bundle: nil)
let vc = mainStoryboard.instantiateViewControllerWithIdentifier("LoginController") as UIViewController
let navigationController = UINavigationController(rootViewController: vc)
self.window!.rootViewController = navigationController
}
self.window!.makeKeyAndVisible()
This will prevent from displaying default view before presenting LoginController.
Or else
In storyboard #1 create a DummyViewController(UIViewController) and make it as InitialViewController and set a Background image(Your SplashScreen Image) to DummyViewController .In viewdidload check for credentials,If You have value
let storyboard = UIStoryboard(name: "storyboard #1", bundle: nil)
let controller = storyboard.instantiateViewControllerWithIdentifier("default view ") as UIViewController
presentViewController(controller, animated: true, completion: nil)
if no credentials go with your given code
let storyboard = UIStoryboard(name: "Authentication", bundle: nil)
let controller = storyboard.instantiateViewControllerWithIdentifier("LoginController") as UIViewController
presentViewController(controller, animated: true, completion: nil)
this too prevents flicker but it is not good way to do.I suggest First Method setting rootviewcontroller.This may help you.Give it a try.
My suggestion is to set launch screen viewcontroller as rootviewcontroller of the application until the all your deciding factor get executed. This is one of the finest approach for async operation.

Present View Controller in Storyboard with a Navigation Controller - Swift

I am currently showing a viewController in my new storyboard below:
var storyboard : UIStoryboard = UIStoryboard(name: AccountStoryboard, bundle: nil)
var vc : WelcomeViewController = storyboard.instantiateViewControllerWithIdentifier("WelcomeID") as WelcomeViewController
vc.teststring = "hello"
self.presentViewController(vc, animated: true, completion: nil)
However, this presents the viewcontroller without its embedded navigation controller.
I tried changing "WelcomeID" to the navigation controller within the storyboard - however to no success.
I got this working in Objective -C, however don't know how to transform into swift:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"SetupStoryboard" bundle:nil];
UINavigationController *navigationController1 = [storyboard instantiateInitialViewController];
navigationController1.modalPresentationStyle = UIModalPresentationFormSheet;
navigationController1.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
WelcomeViewController *vc = (WelcomeViewController *)navigationController1.viewControllers[0];
vc.teststring = #"Hello";
[self presentViewController:navigationController1 animated:YES completion:nil];
How can you do this in swift?
You're definitely on the right track. Unfortunately when you reference a view controller by its storyboard ID it will ignore the fact it is embedded within anything. Same goes for segues when you segue to something embedded, the destination view controller will be the embedding controller, not the controller you're usually interested in. Anyhow, you should be able to fix the problem in a similar way you've done in Objective-C, so this is just an exercise in syntax porting.
Edit: Define storyboard name with string now
let storyboard : UIStoryboard = UIStoryboard(name: "AccountStoryboard", bundle: nil)
let vc : WelcomeViewController = storyboard.instantiateViewControllerWithIdentifier("WelcomeID") as WelcomeViewController
vc.teststring = "hello"
let navigationController = UINavigationController(rootViewController: vc)
self.presentViewController(navigationController, animated: true, completion: nil)
OR you can give your embedding view controller an ID and instantiate that instead.
let secondViewController = self.storyboard?.instantiateViewControllerWithIdentifier("WelcomeID") as SecondViewController
self.navigationController?.pushViewController(secondViewController, animated: true)
Class Name is : SecondCiewController
The answer given by #Chris is works good in older version of swift.
Update Swift 3 & Swift 4
let storyboard : UIStoryboard = UIStoryboard(name: "AccountStoryboard", bundle: nil)
let vc : WelcomeViewController = storyboard.instantiateViewController(withIdentifier: "WelcomeID") as! WelcomeViewController
vc.teststring = "hello"
let navigationController = UINavigationController(rootViewController: vc)
self.present(navigationController, animated: true, completion: nil)
Thanks!!!
Remember to setup the modalPresentationStyle property, in programmatically present the IB settings are ignored.
let sb = UIStoryboard(name: "retail_carrello", bundle: nil)
guard let carrelloVC = sb.instantiateViewController(withIdentifier: "mainCarrello") as? retail_carrello else { return }
let navController = UINavigationController(rootViewController: carrelloVC)
navController.modalPresentationStyle = .fullScreen //<--- remember to set up this if you need fullscreen
present(navController, animated: true, completion: nil)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "SalesVC") as! SalesVC
navigationController?.pushViewController(vc, animated: true)

Present storyboard ViewController from another ViewController

I have multiple UIViewControllers in my iOS App's Storyboard. I want to open one of the UIViewControllers (in the storyboard) from a different UIViewController.
I've tried the code below, but it isn't working even though I used it before iOS 5 and it worked fine.
- (IBAction)addNotes:(id)sender {
NotesViewController *notesView = [[NotesViewController alloc] initWithNibName:#"NotesViewController" bundle:nil];
[self presentModalViewController:notesView animated:YES];
}
How can I perform this action with iOS 5 Storyboards?
Assuming you have storyboard, go to storyboard and give your VC an identifier (inspector), then do:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"IDENTIFIER"];
[self.navigationController pushViewController:vc animated:YES];
Assuming you have a xib file you want to do:
UIViewController *vc = [[UIViewController alloc] initWithNibName:#"NIBNAME" bundle:nil];
[self.navigationController pushViewController:vc animated:YES];
Without a xib file:
UIViewController *vc = [[UIViewController alloc] init];
[self.navigationController pushViewController:vc animated:YES];
Following will work on Swift 3.0 and above.
StoryBoard
let storyBoard = UIStoryboard(name: "Main", bundle: nil)
let mainViewController = storyBoard.instantiateViewController(withIdentifier: "Identifier")
self.navigationController?.pushViewController(mainViewController, animated: true)
.xib
let viewController = UIViewController(nibName: "NibName", bundle: nil)
self.navigationController?.pushViewController(viewController, animated: true)
Without .xib
let viewController = UIViewController()
self.navigationController?.pushViewController(viewController, animated: true)
Swift 5
let storyboard = UIStoryboard(name: "YourStoryboardName", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "ControllerIdentifier")
self.present(vc, animated: true, completion: nil)
Update with the Swift 3.1 version
if you haven't embed navigation controller then
let storyBoard:UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let viewController2 = storyBoard.instantiateViewController(withIdentifier: "ViewController2")
self.present(viewController2, animated: true, completion: nil)
and, if you had embed navigation controller then
let storyBoard:UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let viewController2 = storyBoard.instantiateViewController(withIdentifier: "ViewController2")
self.navigationController?.pushViewController(viewController2, animated: true)
In swift 4.2 answer for those who want this answer without navigation in modally and in swift updated versions.
let storyboard = UIStoryboard(name: "YourStoryboardName", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "mainViewController")
self.present(controller, animated: true, completion: nil)
UIViewController *initialHelpView = [[UIStoryboard storyboardWithName:#"StoryBoard_IDentifier" bundle:nil] instantiateViewControllerWithIdentifier:#"ViewController_Identifier"];
[self presentViewController:initialHelpView animated:YES completion:nil];

Resources