Pushing two Different view controllers in one button action-iOS - ios

My iOS application has four tabs that displays different information.
In my second tab viewController I have one button lets name it as button1 in that button1 action i have navigated to SignInViewController screen and in my third tab view controller is loginViewController.
In both the ViewControllers I have option to register and as well as already existed user can logged in both the ViewControllers.So here in SignInViewController I have a button named it as registerButton. Now in this registerButton action I have pushed RegisterViewController and same as SignInViewController in loginViewController also i have button named it as registerButton2. Now in this registerButton2 Action i have pushed same RegisterViewController.
Here now what i want exactly is in RegisterViewController I have a button lets name it as SaveButton in SaveButtonAction if I am gone through from SignInViewController to RegisterViewController then in SaveButtonAction i want to push ShippingViewController and if I am gone through from loginViewController to RegisterViewController then in SaveButtonAction i want to push `AccountViewController.
in short (1)tabbaritem2-->SignInViewController-->RegisterViewController-->ShippingViewController (2)tabbaritem3-->loginViewControoler-->RegisterViewController-->AccountViewController
I have tried following code in SaveButtonAction but its does not working.
Here is my code:
- (IBAction)SaveButtonAction:(id)sender{
if(_tabBarController.tabBarItem.tag == 2){
UIStoryboard *story = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
ShippingViewController *shipVc = [story instantiateViewControllerWithIdentifier:#"ShippingViewController"];
[self.navigationController pushViewController:shipVc animated:YES];
else if(_tabBarController.tabBarItem.tag == 3){
UIStoryboard *story = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
AccountViewController *acntVC = [story instantiateViewControllerWithIdentifier:#"AccountViewController"];
[self.navigationController pushViewController:acntVC animated:YES];
}
}
kindly help.Thanks in Advance.

Just use a boolean in the RegisterViewController (lets say shouldFromLogin) and while pushing from LoginVC set the boolean as true and in other case pass it as false. Then check that boolean in the button action and navigate to different VC accordingly.
Demo Code :
//This code when you push to RegisterVC from LoginVC. Similar thing for other case with shouldFromLogin as NO.
UIStoryboard *story = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
RegisterViewController *registerVc = [story instantiateViewControllerWithIdentifier:#"RegisterViewController"];
registerVc.shouldFromLogin=YES;
[self.navigationController pushViewController:shipVc animated:YES];
Then check
- (IBAction)SaveButtonAction:(id)sender{
if(shouldFromLogin){
//Pass to AccountViewController
}
else{
//Pass to ShippingViewController
}
}

you can do this using selected tabbar index.
if(theTabBar.selectedItem == 2){
ShippingViewController *shipVc = [story instantiateViewControllerWithIdentifier:#"ShippingViewController"];
[self.navigationController pushViewController:shipVc animated:YES];
}
else if(theTabBar.selectedItem == 3){
AccountViewController *acntVC = [story instantiateViewControllerWithIdentifier:#"AccountViewController"];
[self.navigationController pushViewController:acntVC animated:YES];
}

In your RegisterViewController.h file, declare an enum as below:
typedef NS_ENUM(NSUInteger, RegisterViewControllerAction) {
RegisterViewControllerActionShipping,
RegisterViewControllerActionAccount,
}
Also, declare a new constructor for RegisterViewController class:
#interface RegisterViewController
#property (readonly) RegisterViewControllerAction action;
- (id)initWithAction:(RegisterViewControllerAction)action;
#end
#implementation RegisterViewController
#synthesize action = _action;
- (id)initWithAction:(RegisterViewControllerAction)action {
if (self = [super initWithNib:xxx]) {
_action = action;
}
}
- (IBAction)SaveButtonAction:(id)sender {
if (_action == RegisterViewControllerActionShipping) {
....
} else if (_action == RegisterViewControllerActionAccount) {
....
}
}

//This code when you push to RegisterVC from LoginVC. Similar thing for other case but assign #"signin" instead of #"login".
UIStoryboard *story = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
RegisterViewController *registerVc = [story instantiateViewControllerWithIdentifier:#"RegisterViewController"];
registerVc.imFromLogin = #"login";
[self.navigationController pushViewController:registerVc animated:YES];
- (IBAction)SaveButtonAction:(id)sender{
if([_imFromLogin isEqualToString:#"login"])
{
[self performSegueWithIdentifier:#"regToAccount" sender:nil];
}else if ([_imFromLogin isEqualToString:#"signin"]) {
[self performSegueWithIdentifier:#"registerToShipping" sender:nil];
}
}

Related

Hide LoginViewController or dismiss to parentView

This is a normal LoginView calling on a specific action in my app
sourceViewVontroller
if ([password length] == 0) {
loginViewController *seatView = [mainStory instantiateViewControllerWithIdentifier:#"loggingView"];
[self presentViewController:login animated:YES completion:nil];
}
it checks if user not signed in yet when he's calling this action, so it redirects him to the loginViewController, then
loginViewController
UIStoryboard *mainStory = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
DestinationViewController *Dest = [mainStory instantiateViewControllerWithIdentifier:#"destView"];
[self presentViewController:Dest animated:YES completion:nil];
it goes to the destinationView that needs a login, now my problem is how to go back (dismiss not presentmodalView) to the sourceViewController, or simply, how to remove the loginViewController from the queue on success and dismiss directly to the source?
destinationViewController
// Tried to use presentView .. but i dont need to reload sourceView, just dismiss to it !
//[self presentViewController:srcView animated:YES completion:NULL];
//This is what am doing ..
[self dismissViewControllerAnimated:NO completion:nil];
Or just let me know if there is other professional way to do this login flow
I suggest for you another way:
First in - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
You will check user login or not. If login you will set rootView to destinationViewController. If not set rootView to loginViewController
SampleCode:
UIStoryboard *mainStory = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
if (logged) {
DestinationViewController *Dest = [mainStory instantiateViewControllerWithIdentifier:#"destView"];
self.window.rootViewController = Dest;
} else {
LoginViewController *seatView = [mainStory instantiateViewControllerWithIdentifier:#"loggingView"];
self.window.rootViewController = seatView;
}
When logout you just call notification or delegate set rootViewController of window to loginViewController.
Do not use presentViewController for bringing login controller.
Complete Process :
In Singleton class. set a global property.
#property (assign)BOOL isUserLoggedIn;
When user logs in or logs out, set this variable to true or false.
Set an enum in LoginViewController.
typedef enum {
DestViewControllerOne =1,
DestViewControllerTwo
} SignInType;
In this enum, put all your view controller where you wanna put that login check.
Set a property in login view controller to hold source controller value -
#property (nonatomic, assign) NSInteger signInType;
Set up a delegate in login controller to redirect after successfull login -
#protocol SignInProtocolDelegate <NSObject>
#optional
-(void) signInSuccess:(NSInteger) signInType;
#end
Create a property with that delegate in login controller -
#property (nonatomic, assign) NSObject<SignInProtocolDelegate>* delegate;
Now before proceeding to required view controller, perform below check -
if(![[TESingleton shareData] isUserLoggedIn]){
[self funcNavigateToSignInWithAlert:YES withSignInType:proceedToDestViewControllerOne];
}
else
{
[self proceedToDestViewControllerOne];
}
-(void)funcNavigateToSignInWithAlert:(BOOL)showAlert withSignInType:(NSInteger) signIntype
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:STORYBOARDNAME bundle:nil];
LoginViewController *viewController = (LoginViewController *)[storyboard instantiateViewControllerWithIdentifier:#"LoginViewController"];
[viewController setSignInType:signIntype];
[viewController setDelegate:self];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:viewController];
navController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[[SlideNavigationController sharedInstance] presentViewController:navController animated:YES completion:nil];
}
By this, it will bring login page.
Next -
After successfull login, Do this in login controller :
[self dismissViewControllerAnimated:YES completion:nil];
[[self delegate] signInSuccess:self.signInType];
Import login delegate method in source controller that we have written above -
-(void) signInSuccess:(NSInteger) signInType
{
switch (signInType)
{
case DestViewControllerOne:
[self performSelector:#selector(proceedToDestViewControllerOne) withObject:nil afterDelay:0.5];
break;
case DestViewControllerTwo:
[self performSelector:#selector(proceedToDestViewControllerTwo) withObject:nil afterDelay:0.5];
break;
default:
break;
}
}
Implement these methods in source view controller -
-(void) proceedToDestViewControllerOne
{
//Restricting navigation to signin
//Addded by vikas Jul 8,2015
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:STORYBOARDNAME bundle:nil];
DestViewcontrollerOne *objDestViewcontrollerOne = (DestViewcontrollerOne *)[storyboard instantiateViewControllerWithIdentifier:#"DestViewcontrollerOne"];
[self.navigationController objDestViewcontrollerOne animated:YES];
}
This is complete process.
Use Unwind Segues
Add a method in SourceViewController
For Swift
#IBAction func unwindToThisViewController(segue: UIStoryboardSegue) {
}
For Objective-C
- (IBAction)unwindToThisViewController:(UIStoryboardSegue *)unwindSegue {
}
You can come back to the SourceViewController in two ways.
Using Storyboard e.g when an UIButton action fires.
Using performSegueWithIdentifier in code.
Storyboard:
Control drag form an UIButton in DestinationViewController to Exit segue inSourceViewController
In Code:
Control drag form an UIButton in DestinationViewController to Exit segue inSourceViewController
Call performSegueWithIdentifier:#"ExitToSourceViewController" when need to come back to SourceViewController

how to switch between view inside the uitabbarcontroller in iOS

I am working with UITabBarcontroller, where i want to switch between view s with an UISegmentController, but the UITabBarItem should not be hidden when I click on UISegmentController:
if([sender selectedSegmentIndex] == 0)
{
// UIStoryboard *mystoryboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
// UITabBarController *wc = [mystoryboard instantiateViewControllerWithIdentifier:#""];
// [self.navigationController pushViewController:wc animated:YES];
}
else if([sender selectedSegmentIndex] == 1)
{
UIStoryboard *mystoryboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UITabBarController *wc = [mystoryboard instantiateViewControllerWithIdentifier:#"ProfileViewController"];
[self.navigationController pushViewController:wc animated:YES];
}
I will assume that what you are trying to do is have a secondary tab bar (the segment control) to switch between views inside a primary tab. In this case, I would suggest to use a view container, and make the switch inside it. Something like this:
EDIT
You can try this.
But once it changes in The TabBarController,your current VC changes and you cannot access the SegmentedControl as you are in a new VC now, thus you have to again navigate to the older VC via the Tabbar. But you can try this.
if(self.segmentedControl.selectedSegmentIndex == 0){
[self.navigationController.tabBarController setSelectedIndex:1];
}
else {
[self.navigationController.tabBarController setSelectedIndex:0];
}
This code would work when your storyboard is like this

How to get the navigation bar on view controller?

I have three View controller A,B,C.I have navigation controller attached to A view controller.In A i have some buttons,I have attached the button segue to B view controller.Onclick of the button i go to the B view controller.On B View controller i have UITableView on click of table view item i am launching the C view controller.below is the code for that
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.row==0)
{
NSLog(#"first cell");
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
UIViewController * vc = [storyboard instantiateViewControllerWithIdentifier:#"BusinessCard"];
[self presentViewController:vc animated:YES completion:nil];
}
else if(indexPath.row==1)
{
NSLog(#"second cell");
}
else if(indexPath.row==2)
{
NSLog(#"third cell");
}
}
But on C view controller the navigation Bar is not appearing.I think C view controller is not linked to the Navigation Controller.
You use navigationController push method to display navigation bar in C viewController
try this code:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
UIViewController * vc = [storyboard instantiateViewControllerWithIdentifier:#"BusinessCard"];
[self.navigationController pushViewController:vc animated:YES];
Use the code below
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
UIViewController * vc = [storyboard instantiateViewControllerWithIdentifier:#"BusinessCard"];
UINavigationController *nav=[[UINavigationController alloc] initWithRootViewController:vc];
[self presentViewController:nav animated:YES completion:nil];
You need to present it using UINavigationController as modal.
Hope it helps.
use this:
[self.navigationController pushViewController:vc animated:YES];
You can use "Push" segue and embed your ViewController in Navigation Controller, and then use its Navigation Controller's functions like pushViewController and popViewControllerAnimated
Answer are all correct, but i just want to explain things..
//This line gets the storyboard with the name "Main" which contains all
//the setup you made for UI (User interface)
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
//While this like gets the view inside your storyboard with
//storyboard ID/indentifier `BusinessCard `
UIViewController * vc = [storyboard instantiateViewControllerWithIdentifier:#"BusinessCard"];
//Lastly, this line is correct presenting the viewcontroller BUT this doesn't add your
//viewcontroller to the array of viewControllers inside navigationController
//
//Also, this line makes you present the viewController above the
//rootViewController of window which is in your case the navigationController
//
This is you Error
[self presentViewController:vc animated:YES completion:nil];
//This is what you are looking for, and the correct one for your implementation
//
//This will let you add the `vc`(viewController) to the array of viewController
//in navigationController, to confirm that you can check the `self.navigationController.viewControllers`
//which will return the array of viewController inside your navigationController
This is the Answer
[self.navigationController pushViewController:vc animated:YES];
Hope this helps you, and my explanation is apprehendable.. Cheers

iOS use the delegate pass value not trigger the method

I was test the delegate pass the value in objective-c.
I know there are other methods can pass string between UIViewControllers like NSNotifyCenter..etc.
Now I want to try to use the delegate pass value .
But I encounter some problems.
I use the navigation and there have two UIViewController(FirstUIViewcontroller and SecondUIViewController).
Now I want to use manual to change to SecondUIViewController,not use the button drag to the SecondUIViewController at FirstUIViewController.
So I add the code in the FirstUIViewController.m button action.
- (IBAction)pushBtnAction:(id)sender {
SecondViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
[self.navigationController pushViewController:controller animated:YES];
}
Then I want to pass the value from the SecondUIViewcontroller when I pop the view controller.
So I add the delegate implement and se the delegate in the FirstUIViewController.m.
- (void)viewDidLoad {
[super viewDidLoad];
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
secondVC = (SecondViewController*)[mainStoryboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
secondVC.delegate = self;
}
-(void) passSecondVC:(SecondViewController *)vc didAddValue:(NSString *)str
{
NSLog(#"second str:%#",str);
}
In the SecondUIViewController.h , I had declare delegate method.
#class SecondViewController;
#protocol SecondViewControllerDelegate <NSObject>
#optional
-(void)passSecondVC:(SecondViewController*)vc didAddValue:(NSString*) str;
#end
#interface SecondViewController : UIViewController
#property (nonatomic,assign) id<SecondViewControllerDelegate> delegate;
- (IBAction)passValueDelegatBtnAction:(id)sender;
In the SecondViewController.m ,
when I click the button will pop self uiviewcontroller and pass the value to FirstUIViewController.
- (IBAction)passValueDelegatBtnAction:(id)sender {
if( [self.delegate respondsToSelector:#selector(passSecondVC:didAddValue:)])
{
[self.delegate passSecondVC:self didAddValue:#"this is string from sencond vc"];
}
[self.navigationController popViewControllerAnimated:YES];
}
(My problems)
But in this status , I always can't get the value in the delegate method in the FirstUIViewController.
I had try to other method like below in the FirstViewController.m
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSLog(#"segue");
id vc = segue.destinationViewController;
if( [vc isKindOfClass:[SecondViewController class]])
{
SecondViewController *secondVC = vc;
secondVC.delegate = self;
}
}
There are same problem.
I can't get the value from the delegate method.
Have anyone know where the problems?
I post my completely code in here.
Thank you very much.
Alright!
Remove your code from the viewDidLoad: method and set the delegate when you push the secondViewController.
- (IBAction)pushBtnAction:(id)sender {
SecondViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
[controller setDelegate:self];
[self.navigationController pushViewController:controller animated:YES];
}
So what was going wrong?
Ans: You create a new object in your viewDidLoad: method and set your firstViewController as delegate to it. Now while pushing you are creating another object of SecondViewController whose delegate is not set.
I downloaded your code & fixed it.
You don't want this line. so comment it,
// UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
// secondVC = (SecondViewController*)[mainStoryboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
// secondVC.delegate = self;
Edit this method as below,
- (IBAction)pushBtnAction:(id)sender {
SecondViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
controller.delegate = self;
[self.navigationController pushViewController:controller animated:YES];
}
Also edit this method as below,
- (IBAction)passValueDelegatBtnAction:(id)sender {
// if( [self.delegate respondsToSelector:#selector(passSecondVC:didAddValue:)])
// {
[self.delegate passSecondVC:self didAddValue:#"this is string from sencond vc"];
// }
[self.navigationController popViewControllerAnimated:YES];
}
you forgot some code in pushBtnAction..
- (IBAction)pushBtnAction:(id)sender {
SecondViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:#"SecondViewController"]; // It's different to VC you init in viewDidLoad
controller.delegate = self; // you forgot....
[self.navigationController pushViewController:controller animated:YES];
}
prepareForSegue be call when you use segue to navigation.

How to custom object between two storyboard in one project?

I have two storyboard in my project. I am usually can navigate from one View of storyboard to another View of another storyboard?
I am writing code as below
UIStoryboard* storyboard = [UIStoryboard storyboardWithName:#"Details" bundle:nil];
UIViewController * vc = [storyboard instantiateViewControllerWithIdentifier:#"Detail"];
// Get button tag number (or do whatever you need to do here, based on your object
NSInteger tagIndex = [(UIButton *)sender tag];
vc.modalTransitionStyle =UIModalTransitionStyleFlipHorizontal;
[self.navigationController pushViewController:vc animated:YES];
Now, I have three buttons, and tag on them, How can I pass Custom Object, kept in array to next controller of another storyboard ("DETAIL").
Thanks
Maybe this can help you :
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"storyboard2" bundle:nil];
[self presentModalViewController:[storyboard instantiateViewControllerWithIdentifier:#"storyboard2initialviewcontroller"] animated:NO];
EDIT :
Maybe like this, not sure it will help but i ll try :)
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"MySegue"]) {
MyOtherViewController *destination = (MyOtherViewController *)segue.destinationViewController;
destination.someProperty = self.someOtherProperty;
}
}
and
UIStoryboard *secondStoryBoard = [UIStoryboard storyboardWithName:#"secondStoryBoard" bundle:nil];
MyOtherViewController *myViewController = (MyOtherViewController *)[secondStoryBoard instantiateViewControllerWithIdentifier:#"myOtherViewController"];
myViewController.someProperty = self.someOtherProperty;
[self.navigationController pushViewController:myViewController animated:YES];
You can pass the custom object like below
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:#"Details" bundle:nil];
HomeViewController *homeVC = [storyBoard instantiateViewControllerWithIdentifier:#"view2"];
// here I am passing string to the another controller (i.e HomeViewController), you can pass any object that you want
homeVC.info = #"This is test string";
[self.navigationController pushViewController:homeVC animated:YES];
Hope this helps you

Resources