LoginViewController -> OtherviewController Two-way Segue - ios

I am new to iOS development and XCode and am trying to figure out how to implement the following logic:
1) User starts app - user is directed to the LoginViewController that has a login form
2) Upon successful user login - go to the next view controller - let's call it LoginViewController
How do I programatically do that in the action logic for the login button in the view of LoginViewController e.g.
#IBAction func loginButtonPressed(button: UIButton) {
//do login logic
//what to put here to segue to OtherViewController
}
And once the user is in OtherViewController, it is possible their auth token will expire. If that happens I would need to segue back to LoginViewController. I come from an Android background where you would use Intents to make something like this happen - what is the equivalent in iOS?
An answer in Swift is preferred since I am more familiar with that, but I am decent at deciphering Objective C code as well.
As a side note- should I be controlling segues in code like this or should I be using storyboards? I tried creating segues in the storyboard but I do not understand how to hook those up to application code.

One way:
self.performSegueWithIdentifier("name2", sender: self)
As an example:
#IBAction func button(sender: AnyObject) {
self.performSegueWithIdentifier("newView", sender: self)
}
Here i created a modal segue from viewController1 to ViewController2 in the storyboard. I did this by control-click on the yellow ViewController icon at the top of the view and drag the blue line to the second view. Then release. in the popup menu select modal segue. Then in the utilities panel on the right - after highlighting the segue in the storyboard, click on the attributes inspector and give the identifier a name. Then paste that name in the code example where I have "newView".

Actually you can init you next controller from storyboard:
UIStoryboard * storyboard = self.storyboard;
OtherViewController * otherVC = [storyboard instantiateViewControllerWithIdentifier: # "xxx * Name Desire"];
If you use navigation controller:
[self.navigationController pushViewController: otherVC animated: YES];
Else:
[self presentViewController:otherVC animated:YES completion:nil];

Related

popToRootViewController not working when sending from add screen

I have a simple app I am building. A list of items in 1 view controller with a table view and embedded navigation controller. When you select a row it brings you to the details screen (no problem).
Push from List View to List Item
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "ListItemDetailsVC", sender: nil)
}
Pop back from list item to List View
#IBAction func backToInboxTapped(_ sender: Any) {
navigationController?.popToRootViewController(animated: true)
}
This works fine!
My issue is that I have another view controller (add item) that presents modally when add button is clicked. The idea is that when it saves it brings you to the list detail vc.
#IBAction func saveItem(_ sender: Any) {
performSegue(withIdentifier: "DetailsFromAdd", sender: nil)
}
Opening up the details view controller from the add new controller works fine but once I open the details view I want to be able to go back to the rootViewController. The button does not work anymore
In your case you should not need to use segue. You have to clear some concepts.
You can't popToRootViewController or VC if you have pushed or show view controller from modally presented vc!!
Now if you want to achieve this then you have to make some changes that I am trying to mention below :
take one global variable or property (objective c concept) in your add item VC. now when you come to add item VC from lust VC set this global variable or property to self something like,
AddListItemVC *advc = [self.storyboard instantiateViewControllerWithIdentifier:#"addListItem"]; // addListItem is storyboard id for viewcontroller
[self presentViewController:advc animated:NO completion:^{
advc.vc = self; // here vc is the propery of type `UIVIewController` declare in AddListItemVC
}];
Now your code for going to details VC from add list VC should be like,
DetailListViewController *dvc = [self.storyboard instantiateViewControllerWithIdentifier:#"detailViewScreen"]; // detailViewScreen is storyboard id which you can set from identity inspector
[self dismissViewControllerAnimated:NO completion:^{
[self.vc.navigationController pushViewController:dvc animated:YES]; // here self.vc is global variable or property that contains reference of first VC (i.e. list view controller)
}];
no need to use performsegue in this case. You can use performsegue to go in detailvc directly from firstvc i mean from list vc.
Hope you got understand concept and i have written objective c snippet because of lake of time!! hope you can easily convert to swift!!
Firstly, As you say that addVC is modally presenting so make sure addVC have some navigation otherwise you'll not able to push listItemVC from addVC.
Now second thing, when you're modally presenting addVC then push listItemVC pushed from addVC, now addVC navigation controller have two view controllers. When you call navigationController?.popToRootViewController(animated: true) this will bring you to addVC because is being presented thats's why you will not able to see listVC.
To solve this you've to add some dismiss presented view controller whenever you'll arrive at addVC.

implement login screen before swrevealcontroller

I've just started learning IOS development, I've successfully implemented the SWRevealViewController by following a given tutorial online all is working as expected.
I've then decided to add a login screen, which would be the first page the user see's when the application is run. The steps I took are a follows:
Dropped a UIViewController onto the story board
Set this as my 'is initial view controller'
Added a button to this new view and created a seque for testing purposes
But when I click this button it does nothing, so after searching the web and trying to figure this one by my self unfortunately I've been unsuccessful due to my lack of knowledge on this, would someone be kind enough to give me some pointers on what I need to change if anything, or what sections need to me modified to make this flow work as expected?
Below is a screen grab of my current story board.
Update
After adding the relevant code the app delegate file I still receieve this error message:
Step-1
embed your login VC to NavigationController.
Step-2
on your login button action set the segue type as Modal and call as
#IBAction func btnLogin(sender: AnyObject) {
self.performSegueWithIdentifier("openSWL", sender: self)
}
For flow understand purpose
For sample Project you can download here
The Storyboard arrangement looks good. I have used SWRevealController like below:
After you login (performing login service or some login process) write below code.
This code will change current rootViewController (In your case it is LoginViewController) to SWRevealController. So that it will work. And when ever you do logout change rootViewController to LoginViewController.
SWRevealViewController *controller = (SWRevealViewController *)[self.mainStoryboard instantiateViewControllerWithIdentifier:#"RevealViewController"];
[self.window setRootViewController:controller];
Do not forget to assign StoryboardID = "RevealViewController" in Storyboard for SWRevealViewController.
Swift Code:
Add below function to your AppDelegate.swift file:
func changeRootViewControllerToSWRevealViewController () {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let controller = storyboard.instantiateViewControllerWithIdentifier("RevealViewController")
if let window = self.window{
window.rootViewController = controller
}
}
// Call above function in your login button action method like below:
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.changeRootViewControllerToSWRevealViewController()

Making a segue through button action

I am trying to make a login in screen where when you press login it will check the username and password then if it is all good it will segue to the next view.
I have 1 view controller with 2 buttons just to test that I can successfully segue with a button action to another view controller. 1 button is my attempt to programmatically link the two view controllers and the other button is linked by a modal and it successfully switches between the views.
for the first button my code is,
#IBAction func testButton(sender: UIButton) {
performSegueWithIdentifier("nextView", sender: self)
}
for the storyboardID of the view controller to be switched to it is indeed 'nextView'
I get an error, 'NSInvalidArgumentException', reason: 'Receiver has no segue with identifier 'nextView'
I have cleaned up the code and also tried removing the app from the simulator.
Any suggestion on what the issue may be? Or is there a better way to make a login screen?
In order to perform segue on button tap with custom logic, select controller one (not button) control drag and drop on controller two. chose the segue and give an identifier value in storyboard. Then when you call performSegueWithIdentifier, it will work.
You need to set the identifier for the segue, not the StoryboardID of the view controller:
try this UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainstoryBoard" bundle:nil];
ViewController* viewController = [storyboard instantiateViewControllerWithIdentifier:#"StoryBoardIdentifier"];
[[self navigationController] pushViewController:viewController animated:YES];
performSegueWithIdentifier refers to the id of the segue not the storyboardID of the viewController you're trying to load. That being said, you could either create a segue between the view controller you're on to the destination view controller and use performSegueWithIdentifier, or you could create an instance of your storyboard and use its instantiateViewControllerWithIdentifier method which takes the storyboardID as a parameter. I'm posting from mobile so that might not be exact, but that should help you out.

Redirect to new view controller in the middle of navigation stack

I am fairly new to navigation view controllers and stacks in iOS. Please help me with this, tried searching for a long time couldn't find anything relevant.
I have a LoginViewController, a SWRevealViewController for side menu operation, a FirstViewController (the first one in navigation stack) and a SecondViewController (second in navigation stack).
I have to do the following in LoginViewController, assume login and found are two boolean variables:
if (login && !found) {
//redirect to FirstViewController : the following works
[self presentViewController:swReveal animated:NO completion:nil];
}
else if (login && found) {
//redirect to SecondViewController
}
Please help me fill the else if. Really appreciate your time!
So based on what I understood from your comments, FirstViewController is a subclass of TableViewController and SecondViewController is the DetailView.
So based on that, the best approach for "redirecting" to the DetailView (SecondViewController), would be creating a segue on the Storyboard, and then calling that segue programatically once the FirstViewController is loaded (in its viewDidLoad)
On both cases you would first show the FirstViewController and then depending on the if statement, you would either stay or go to the SecondViewController.
So first step: Create the segue from the Storyboard, and give it an identifier.
Second: Perform that segue programatically when the FirstViewController is loaded (and of course, the if statement is valid) by using:
[self performSegueWithIdentifier: #"MySegue" sender: self];
More on that subject:
Alternative ways to push view controllers with storyboard programmatically
Creating a segue programmatically

Move to another ViewController

Im using StoryBoard and i am not so sure how to instantiate a ViewController or how to reference one.
The thing is i have two view controllers and i have one with a button. I want to go to the other view controller when i pressed the button from the first view controller.
I have tried something like that:
let secondViewController:UIViewController = UIViewController()
self.presentViewController(secondViewController, animated: true, completion: nil)
Does anyone knows how to explain it to me? Thanks!
There are couple of ways of navigating between view controllers. Here's how you do it in code without segues if you're going that way.
Presenting a view controller modally.
Say you have 2 view controller scenes in the storyboard, FirstViewController and SecondViewController. You want to transit from FirstViewController to SecondViewController and there is no segue between them.
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let secondViewController = storyboard.instantiateViewControllerWithIdentifier("SecondVC") as UIViewController
presentViewController(secondViewController, animated: true, completion: nil)
The important part is the that you have to assign an identifier to the view controller you want to go. In this case its the SecondViewController. The way you assign an identifier is you select the view controller, open up the right panel and in it, go to the Identity Inspector (the third one from the left) and under the Identity, assign an identifier to the Storyboard ID field. I put mine as SecondVC as you can see from the code snippet above.
Push to another view controller.
If you want to push on to another view controller instead of presenting it, all you have to do is embed the FirstViewController in a UINavigationController and change the code to this.
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let secondViewController = storyboard.instantiateViewControllerWithIdentifier("SecondVC") as UIViewController
navigationController?.pushViewController(secondViewController, animated: true)
In a comment of yours I saw you want to go to the next view controller based on a condition. Well all you have to do is check your condition in a if else statement and execute either of those above code.
Using Segues.
If you're going to use segues instead of code, here's how you do it.
In the storyboard first you select the button and Ctrl drag to the other view controller. You'll be prompted to choose between different segues. Select show for push or show detail for modal transition (I've explained what these are below). And that's it! If you run it and tap the button, you'd be taken to the other view controller.
But if you want more control over this, you have to do a little more work.. Instead of creating a segue directly from the button, select your view controller and select that little yellow icon on top (This is in Xcode 6. In older Xcode versions its under the view controller scene). Ctrl drag from that icon to the other view controller you want to transit to. You can see a connection appears between those two controllers. Select the segue and open up the right panel and go to the Attributes Inspector (The forth one from the left). Give a name to the field identifier. I gave ToSecond.
Now create a normal action from the button. And you have to call a method called performSegueWithIdentifier passing that identifier. What it does is basically execute a segue with the identifier we give.
#IBAction func segueButtonPressed(sender: UIButton) {
performSegueWithIdentifier("ToSecond", sender: nil)
}
And this would work. You can do the conditions checking here inside a if else and if the conditions are met, call performSegueWithIdentifier.
One other thing you're likely to face is having multiple buttons in a view controller and segueing to different view controller when you tap each of them. A method called prepareForSegue fires each time a segue happens. And inside it, you can check for current segue identifier and execute it. The below code snippet will make this clearer.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "ToSecond" {
let secondViewController = segue.destinationViewController as SecondViewController
}
}
Another thing I'd like to mention is that presentViewController and pushViewController are deprecated from iOS8. Instead you can use showDetailViewController for modal and showViewController to push.
showDetailViewController(secondViewController, sender: nil)
navigationController?.showViewController(secondViewController, sender: nil)
I'm not sure if these are backwards compatible. Meaning using show and show detail will work if you're developing for iOS 7 as well. If you are then just stick with the older methods.
First set seques of uistoryboardviewcontroller and try this
self.performSegueWithIdentifier("push", sender: self)
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
if segue.identifier == "push" {
}
In the storyboard, select VC1 and then select the button and press control and while holding down the left button or touchpad drag across to your VC2. Then a menu should pop up. Select modal.
Run and Test. It should now perform a transition.
To transition back, the easiest way is to embed VC1 in a Navigation Controller. To do this, zoom out, select VC1 and go to the top of the screen and select:
Editor > Embed > Navigation View Controller.
Now test and run. You should have the option to go back.
If you are binding view controller programmatically you need to follow this step if you are creating storyboard based application.
It is similar what we don in Objective-c just the syntax has changed.
According to your question what you need to do is go to Main.storyboard and need to select identity inspector.
There you will be able to view identity which contains two fields
1.) Storyboard ID
2.) Restoration ID
Give them the name of view controller you have binded with class in storyboard id and select check box below restoration id. It will automatically copy storyboard ID in restoration ID.
You need to do same for all your view controllers.
let secondView = self.storyboard?.instantiateViewControllerWithIdentifier("SecondViewController") as SecondViewController
self.presentViewController(secondView, animated: true, completion: nil)
you need to write the name you have entered in Storyboard ID for self.storyboard?.instantiateViewControllerWithIdentifier("/* Storyboard ID */")
You can also visit the link:
Instantiate and Present a viewController in Swift
okay,
in interface builder control click on your button and drag the blue line that appears to the second view controller. The second view controller will highlight blue. You can release and the button is connected. In the popup menu select "modal segue". No code necessary. XCODE handles it.
Watch this video for a demo.

Resources