Storyboard UITabBaar, initiate two different views from button - ios

I've created a storyboard that has a UITabbarController all is working well but now I want to add some logic that determines which viewcontroller a particular tabbar button will display.
Example... if a customer has a valid subscription display viewcontroller one, if no subscription display viewcontroller two.
Is this possible using storyboards, I've looked at UITabBarDelegate and prepareForSegue but struggling to piece this together?
Are there any examples of how to do this sort of thing using StoryBoards?
Many thanks

You can set it like this:
if(hasSubscription)
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:nil];
ViewController1* subsection = [storyboard instantiateViewControllerWithIdentifier:#"ViewController1"];
ViewController2* subsection1 = [storyboard instantiateViewControllerWithIdentifier:#"ViewController2"];
[(UITabBarController*)self.window.rootViewController setViewControllers:[NSArray arrayWithObjects:subsection,subsection1, nil]];
}

If you want to add rootviewController according to the subscription then above answer given by soryngod is good one.
But if you want to open viewControllers after rootviewcontroller loaded, then at tabBarButton press perform following code:-
before this code, add yours viewControllerONE and viewControllerTWO to the rootViewController by segues as shown: . And give each segue an identifier in AttributeInspector, example "one" for viewControllerONE and "two" for viewControllerTWO.
then at tabBarButton action do the following:-
if(subscription)
[self performSegueWithIdentifier:#"one" sender:self];
else
[self performSegueWithIdentifier:#"two" sender:self];

Related

Navigation between Controllers - Black Screens

I'm trying to work on a simple login application which on successful login displays a menu page. On the action sheet of menu page, we have an option of looking at all the users logged in that phone and clicking on any user, it should do some login processing and direct to menu page again. This is how the workflow should go on.
Below is the image that explains it.
All the controllers are connected to segues except for accounts controller and middle controller. Navigation between those two is done using pushViewController as I had to pass some info from accounts controller(table view controller with list of all users) to middle Controller.
MiddleController *maController = [[MiddleController alloc] init];
if (maController.view) {
maController.ma_userId = mo_userId; // Set the exposed property
maController.ma_password = mo_password;
[self.navigationController pushViewController:maController animated:YES];
Middle controller is doing all the process perfectly after getting the details. But directing to menu controller is where I'm facing the problem. If I use a segue between middle controller and menu controller an error is thrown saying no identifier with the name segueName found. But if I use a pushViewController then it is displaying a blank black screen. Can some help me to solve this.
This is how I'm pushing it:
MenuTableViewController *mapMenuTableviewController = [[MenuTableViewController alloc]init];
[self.navigationController pushViewController:mapMenuTableviewController animated:NO];
I've tried all the ways that are posted in previous SO questions, but nothing helped.
Thanks in advance
Try not to alloc-init, but instantiate it fom storyboard like this (you should add it a storyboard id)
YourViewControllerClass *viewController = [[UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil] instantiateViewControllerWithIdentifier:#"ViewController"];
And then push it.
You need to add storyboard id like this
And use like
UIViewController *viewController = [[UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil] instantiateViewControllerWithIdentifier:#"ViewControllerID"];
Go to your storyboard, and set an identifier like this :
Now, in your view controller, do this :
YourViewController *viewController = [[UIStoryboard storyboardWithName:#"<your storyboard name>" bundle:nil] instantiateViewControllerWithIdentifier:#"myViewControllerID"];
[self.navigationController pushViewController:viewController animated:NO];
UPDATE -
Push you Accounts view controller and Middle view controller the way i told before.
Then, when your processing is done in the middle controller, just do this :
[[self presentingViewController]presentingViewController]dismissViewControllerAnimated:NO completion:nil];
Add storyboard Id to yput interface builder "SendSMSViewController" and call below code.
let SendSmsVC = self.storyboard?.instantiateViewControllerWithIdentifier("SendSMSViewController") as! SendSMSViewController
self.navigationController?.pushViewController(SendSmsVC, animated: true)
Plz use this code you will go to MenuTableViewController.
for (UIViewController *controller in self.navigationController.viewControllers)
{
if ([controller isKindOfClass:[MenuTableViewController class]])
{
[self.navigationController popToViewController:controller animated:YES];
break;
}
}

Load a view that is previously loaded in iOS

I have been searching around about this problem, but haven't got any answer yet. My problem is: I have a push button that when clicked will push to another view.
Here is how I push it:
ViewController *vc = [[UIStoryboard storyboardWithName:#"Main" bundle:nil]
instantiateViewControllerWithIdentifier:#"Main_View"];
[self.navigationController pushViewController:vc animated:YES];
The ViewController vc is the view that I pushed. So in the new view, there is a Back button that can drop the current view and comeback to the old view. When I click the push button, the vc been load again from allover.
How can I make the instance of vc stay in memory, so when I go back to old view and come to vc again, it doesn't need to reload again?
I guess it is something related to navigationController stack, but don't know how to do that.
Thanks
Just keep a ViewController instance as property in your first ViewController
#property (strong,nonatomic)ViewController * vc;
Then when push it,check if it is in memory
if (self.vc == nil) {
self.vc = [[UIStoryboard storyboardWithName:#"Main" bundle:nil]
instantiateViewControllerWithIdentifier:#"Main_View"];
}
[self.navigationController pushViewController:self.vc animated:YES];
Are you using a UINavigationController? If so, can call the following line of code in you back button 'IBAction':
[self.navigationController popViewControllerAnimated:YES];
If you really need to keep a instance of the view controller, do what Leo suggested.

How to reference a ViewController in storyboard with PresentViewController

I have four tabs in a UITabBarViewController. Each view has UIButtons added to their navbar's, and each tab has a "post button" that will take the user to the post page.
How do I make reference to a ViewController that is sitting in my storyboard already so that I can pass it into the PresentViewController: method?
for example, this is the method used when the post button is clicked from any of the four tab bar views:
- (void)postInvoked:(UIBarButtonItem *)sender
{
[self presentViewController:______ animated:YES completion:nil];
}
What goes in the blank? I think I need to avoid referencing the UIViewController like this:
UIViewController * postPage = [[UIViewController alloc] init];
as this would create a new instance of the page every time the user navigates to the page.
You have to create instance of controller that you want to present:
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle: nil];
UIViewController *controller = [mainStoryboard instantiateViewControllerWithIdentifier: #"<Controller ID>"];
This will create controller with preconfigured views from storyboard.
#"Controller ID" == "Storyboard ID" attribute in the Interface Builder. (Inspector tab when controller is selected)
And present it as you want.
[self presentViewController:controller animated:YES completion:nil];
It depends.
A VC that is "sitting in your storyboard" doesn't exist. That's just a template that lets you create new copies of the VC when you need it.
If you already have a copy of this VC in memory, just pass a pointer t out in your call to presentViewController:animated.
If not, you need to give it a unique ID in the storyboard, and then use the UIStoryboard method instantiateViewControllerWithIdentifier: to create an instance of the VC, then pass a pointer to the newly-created VC to presentViewController:animated
1)In the story board, click on the viewcontroller you want to present then in the utilities pane, click on the identity inspector.
2)In the storyboard ID enter any string, for example "postView".
3)Edit the method to this:
- (void)postInvoked:(UIBarButtonItem *)sender
{
[self presentViewController:[self.storyboard instantiateViewControllerWithIdentifier:#"postView"] animated:YES completion:nil];
}
In other words:
Assuming that you add the storyboard ID, the blank space should be filled in with
[self.storyboard instantiateViewControllerWithIdentifier:#"storyBoardIDHere"]
Hope this helps.

Unable to pushViewController iOS

I am using storyboard in my app, :
I have Button in my View, On click of button i want to navigate to new View
But when i click on button nothing happens,
Here is my Code:
- (IBAction)JoinClicked:(id)sender{
JoinWithViewController *detail_view_controller = [[JoinWithViewController alloc] initWithNibName:#"JoinWithViewController" bundle:nil];
[self.navigationController pushViewController:detail_view_controller animated:YES];
}
Where i am doing mistake , please help.
Thanks in advance.
Set storyboard id of view controller in story board in identity inspector
Make a reference to your storyboard like
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
then to your controller
YourController *vc = [storyboard instantiateViewControllerWithIdentifier:#"YourController"];// storyboardId
[self.navigationController pushViewController:vc animated:YES];
and you can also make segue and do
[self performSegueWithIdentifier:#"YourSegueIdentifier" sender:sender/nil];
use this one :
- (IBAction)JoinClicked:(id)sender{
[self performSegueWithIdentifier: #"JoinWithIdentifier" sender: self];
}
and add segue in storyborad like
Make an identifier for your push-segue in storyboard.
then use
[self performSegueWithIdentifier:#"YourSegueIdentifier" sender:nil];
When using story boards you should use segues for as much navigation as possible.
Your code seems fine, please verify your outlets correctly configured or not in xib or storyboard.
Edit:
You are using storyboard and wants the xib file to get pushed onto your view controller if I am not wrong, you can drag another view controller in storyboard and name it JoinWithViewController and push using segue on button click. That is much easier than what your trying to do here.

Multiple entry points to a storyboard

I need to make a set of decisions in the AppDelegate on launch - depending on the outcome of those decisions I need to go to specific parts of the storyboard.
So my question is - WITHOUT using any nav or tab controllers, how do I go to a specific part of a storyboard?
OR
Is the only supported option having multiple storyboards - for each of the 'outcomes' and then loading those as required?
Thanks
Give each ViewController a unique identifier in the storyboard.
Then in the appDelegate:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"PUT_UNIQUE_ID_HERE"];
//DO WHAT YOU WANT WITH YOUR VIEWCONTROLLER
//Example:Set it as the root view of the app window...
Give each of your ViewControllers a separate ID, and then instantiate the required one with:
UIViewController *initialVC = [storyboard instantiateViewControllerWithIdentifier:#"<identifier>"];

Resources