How to switch to next controller on button click in ios (programmaticaly) - ios

I am working on single view application. On click of button i want to switch to next page(let say menu controller). Please specify what changes I have to make in appdelegate to add a navigation controller as I am completely new to iOS.
[button addTarget:select action:#selector(buttonClick) forControlEvents:UIControlEventTouchUpInside]; and implement the selector as
-(void)buttonClick{
UIViewController *menu = [[UIViewController alloc] init];
[self.navigationController pushViewController:menu animated:YES];
}

Add this in the app delegate for the root view controller:
FirstViewController *firstViewController = [[FirstViewController alloc] initWithNibName:#"view name" bundle:nil];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:firstViewController];
self.window.rootViewController = navigationController;
Inside the button click:
SecondViewController *secondViewController = [[SecondViewController alloc] initWithNibName:#"view name" bundle:nil];
[self.navigationController pushViewController:secondViewController animated:YES];

you have to set UINavigationController as Window.rootViewController like below.
FirstViewController *viewController = [[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
self.window.rootViewController = navigationController;

You should subclass UIViewController and implement the view however you want. Views can be built programmatically or in interface builder.
Then you would either use segues, storyboard identifiers, or a xib file to load the view.
Might look like this: (assuming you set up the view controllers in a storyboard and connected them with appropriate segues & the identifier below)
-(void)buttonClick{
[self performSegueWithIdentifier:#"MySegueIdentifier"];
}
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString: #"MySegueIdentifier"]) {
MyCustomViewController* vc = (MyCustomViewController*)[segue destinationViewController];
//do something with your view controller, like set a property
}
}
Or maybe like this
-(void) buttonClick {
MyCustomViewController* vc = (MyCustomViewController*)[[UIStoryboard storyboardWithName: #"MyStoryboard"] instantiateViewControllerWithIdentifier: #"MyStoryboardIdentifier"];
[self.navigationController pushViewController: vc animated: YES]; //assuming current view controller is a navigation stack. Or could also do presentViewController:animated:
}
You would add a class subclassing UIViewController to your project, and import it (#import "MyCustomViewController.h" in the .m file of the view controller you're pushing from).
Could also use a xib file, but I won't bother with those since Storyboards are much easier to work with.
Without a storyboard:
Inside the app delegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
navigationController = [[UINavigationController alloc] init]; //navigation controller is a property on the app delegate
// Override point for customization after application launch.
FirstViewController *firstViewController = [[FirstViewController alloc] init];
[navigationController pushViewController: firstViewController animated:NO];
[window addSubview:navigationController.view];
[window makeKeyAndVisible];
return YES;
}
Inside your FirstViewController:
-(void) buttonClick {
MyCustomViewController* vc = [[MyCustomViewController alloc] init]; // or maybe you have a custom init method
[self.navigationController pushViewController: vc animated: YES];
}

Very simple:
-(void)ButtonClickActionMethod
{
[button addTarget:select action:#selector(buttonClick) forControlEvents:UIControlEventTouchUpInside];
}
Clicked Action:
-(void)buttonClick{
YourViewController *view = [[YourViewController alloc] initWithNibName:#"YourViewController" bundle:nil];
[self.navigationController pushViewController:view animated:YES];
}

Related

present a new ViewController but maintain the view stack

I'm trying to update an old IOS (objective-c) app to handle shortcutitems. When the user starts the app from a shortcut I would like to go the viewcontroller they've chosen, but would like them to be able to move back through the view hierarchy, to the original launch screen.
the current code in appdelegate didFinishLaunchingWithOptions looks like this:
UINavigationController *controller = (UINavigationController*)[storyboard instantiateInitialViewController];
self.window.rootViewController = controller;
return YES
And trying this:
UINavigationController *controller = (UINavigationController*)[storyboard instantiateInitialViewController];
self.window.rootViewController = controller;
...
if (fromShortCut) {
InfoViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"info"];
// init vc
vc.info = .....
[controller.navigationController pushViewController:vc animated:NO];
// or [controller pushViewController:vc animated:NO];
}
return YES
Shows the correct View, but there's no Back/Back-arrow or swipe gesture to allow the user to move back to the main screen.
Is this possible?
Many Thanks.
Here you go for your solution
if (fromShortCut) {
InfoViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"info"];
UIViewController *rootController = [UIApplication sharedApplication].keyWindow.rootViewController;
// init vc
vc.info = .....
[rootController.navigationController.navigationBar setHidden:NO];
[rootController.navigationController pushViewController:vc animated:NO];
// or [controller pushViewController:vc animated:NO];
}
else{
UINavigationController *controller = (UINavigationController*)[storyboard instantiateInitialViewController];
self.window.rootViewController = controller;
}
Yes. This is possible.
UINavigationController has a setViewControllers:animated: method that lets you do exactly that.
Pay attention to the documentation here:
viewControllers
The view controllers to place in the stack. The
front-to-back order of the controllers in this array represents the
new bottom-to-top order of the controllers in the navigation stack.
Thus, the last item added to the array becomes the top item of the
navigation stack.
You should create an array of UIViewController objects and the order should like this.. [firstVC, secondVC, ..., topMostVC]
EDIT:
The code should look something like this
UINavigationController *controller = (UINavigationController*)[storyboard instantiateInitialViewController];
self.window.rootViewController = controller;
if (fromShortCut) {
NSMutableArray *viewControllers = [[NSMutableArray alloc] init];
//create other viewonctollerObjeccts
FirstViewController *firstVC = storyboard instantiateViewControllerWithIdentifier:#"first"];
SecondViewController *secondVC = storyboard instantiateViewControllerWithIdentifier:#"second"];
ThirdViewController *thirdVC = storyboard instantiateViewControllerWithIdentifier:#"third"];
InfoViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"info"];
// init vc
vc.info = .....
[viewControllers insertObject:vc atIndex:0];
//finally set the array to nav stack
[controller setViewControllers:viewControllers animated:NO];
}
What this does is, it sets InfoViewController at the top of the navigation stack, and backs out to ThirdViewController which backs out to SecondViewController and so on.

How to navigate to UIViewController which is not present in navigationStack

I have three UIViewControllers. I am navigating to VC3 from VC1. I want to navigate to VC2 if I click on cancel or done button from VC3.
I have added the VC2 controller to navigation stack programmatically.
DocListViewController *temp1 = [[DocListViewController alloc] initWithNibName:#"DocListViewController" bundle:nil];
[self.navigationController addChildViewController: temp1];
for (UIViewController *controllers in self.navigationController.viewControllers) {
if([controllers isKindOfClass: [DocListViewController class]]) {
DocListViewController *VC2ViewController = (DocListViewController*)controllers;
[self.navigationController popToViewController:VC2ViewController animated:YES];
}
}
What you are doing wrong here is adding it as child view controller,addChildViewController as it as a child of the current view controller does not add it in the navigation stack.
You need to insert the controller in you navigation stack before doing popToViewcontroller.
VC2 *temp1 = [[VC2 alloc] initWithNibName:#"DocListViewController" bundle:nil];
NSMutableArray *vcArray = [NSMutableArray arrayWithArray:self.navigationController.viewControllers] ;
[vcArray insertObject:temp1 atIndex:1]; // ** This index is `1` assuming you only have 2 controllers and we are pushing it in the middle,
// if you have many vc in navigation stack and just want to insert a new vc just before your current vc go with this:
/*
[vcArray insertObject:temp1 atIndex:vcArray.count - 2];
*/
self.navigationController.viewControllers = vcArray;
/* --- ** This part is also not needed:
for (UIViewController *controllers in self.navigationController.viewControllers) {
if([controllers isKindOfClass: [DocListViewController class]]) {
[self.navigationController popToViewController: controllers animated:YES];
}
}
*/
[self.navigationController popViewControllerAnimated:true];
Also: you don't need VC2 *VC2ViewController = (VC2*)controllers;
inside the if block as you only need a UIViewController type object for pop-ing.
I have just edited your code, get the project reference below
Edit:
Adding GitHub link for better reference:
PlayingWithNavigation
You can navigate to VC2 using pushviewContoller
NSString * storyboardName = #"Main";
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle: nil];
VC2 * VC2View = [storyboard instantiateViewControllerWithIdentifier:#"VC2ID"]; // "VC2ID" is the storyboard Id of your view controller
[self.navigationController pushViewController:VC2View animated:YES];
UIViewController *vc2 = [[UIViewController alloc] init];
UIViewController *vc3 = [[UIViewController alloc] init];
[self.navigationController pushViewController:vc2 animated:NO];
[self.navigationController pushViewController:vc3 animated:YES];
Try this.

iOS How can I use pushviewcontroller with NavigationController(Objective - c)

I want to change view by clicking button with NavigationController
So I added a button to Main.storyboard and write some codes like
#property (weak, nonatomic) IBOutlet UIButton *button;
in my ViewController.m (Created automatically when I made my project)
And I added method
- (IBAction)buttonClicked:(id)sender {
SecondViewController *secondViewController = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
[self.navigationController pushViewController:secondViewController animated:YES];
}
(I made SecondViewController.m, SecondViewController.h, SecondViewController.xib)
After this, I started the application and clicked the button but the screen didn't change.
Actually, when I added log like
NSLog(#"%#", self.navigationController);
null was printed.
I think I need to add some code about NavigationController to AppDelegate.m but I don't know what to do. Please help me.
Try This,
in Appdelegate.m
`- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController"
bundle:nil];
UINavigationController *navigation = [[UINavigationController alloc]initWithRootViewController:self.viewController];
self.window.rootViewController = navigation;
[self.window makeKeyAndVisible];
return YES;
}`
You need to embed Navigation Controller through code or Storyboard.
First select your initial viewcontroller in storyboard and embed it in NavigationController.
Then give a storyboard identifier to the second viewcontroller.
Then lastly instantiate Second ViewController from storyboard and push it.
- (IBAction)buttonClicked:(id)sender {
SecondViewController *secondViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
[self.navigationController pushViewController:entryController animated:YES];
}

Set rootViewController inside a class of UINavigationController

I have a UINavigationController in my storyboard and two viewControllers which perform the following function:
InitialViewController: this would be the application's home screen.
FirstTimeViewController: is the screen that appears when the user open
the app for the first time.
My UINavigationController has a class that have the following code:
- (void)viewDidLoad {
[super viewDidLoad];
if ([[ReadPlist initWithPlist:#"Configuration.plist" key:#"initialConfiguration"] boolValue]){
FirstTimeViewController *firstTimeController = [[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:#"firstTimeView"]; //or the homeController
[self.navigationController pushViewController:firstTimeController animated:NO];
}else{
InitialViewController *initialController = [[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:#"initialView"]; //or the homeController
[self.navigationController pushViewController:initialController animated:NO];
}
}
Basically this code verify the .plist file if a particular field is active, if YES means that the application is running for the first time, in this case it calls the corresponding viewController.
But this code is not working and I see a NavigationController with a black view. All I would do is the same thing we do in the interface builder, simply drag a line from the UINavigationController inside a UIViewController and set as "Root View Controller", but in my case I'm trying to do this programmatically.
How I can do this?
When you push to FirstTimeViewController Set Bool (User Default) in controller ViewDidload Or in your Success Code.then after set in your AppDelegate below code.
if(Bool value = Yes)
{
FirstTimeViewController *FS=[[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:#"FirstTimeViewController"];
UINavigationController *navController=[[UINavigationController alloc]initWithRootViewController:FS];
[navController setNavigationBarHidden:YES];
self.window.rootViewController=navController;
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
}
My answer is
- (BOOL)application:(UIApplication *)app didFinishLaunchingWithOptions:(NSDictionary *)options
{
UINavigationController *navController = (UINavigationController *)self.window.rootViewController;
FirstTimeViewController *firstTimeVC = [navController.storyboard instantiateViewControllerWithIdentifier:#" FirstTimeViewController"];
InitialViewController *initialVC = [navController.storyboard instantiateViewControllerWithIdentifier:#" InitialViewController"];
if ([[ReadPlist initWithPlist:#"Configuration.plist" key:#"initialConfiguration"] boolValue])
{
// FirstTime
navController.viewControllers = [NSArray arrayWithObject:firstTimeVC];
}
else
{
// Initial
navController.viewControllers = [NSArray arrayWithObject:initialVC];
}
[self.window makeKeyAndVisible];
return YES;
}

Xcode UIViewController to customUIViewController without IB

I have a UIViewController, and inside that view controller I would like to call a CustomUIViewController without the use of Interface Builder. I've been using this and it works but it requires a storyboard ID.
UIStoryboard *storyboard = self.storyboard;
UIViewController *myVC = (UIViewController *)[storyboard instantiateViewControllerWithIdentifier:#"PageID"];
[self presentModalViewController:myVC animated:YES];
Is there a way of going from a UIViewController to a customViewController without the use of segues and IB?
Use this:
UIViewController *myVc = [[UIViewController alloc] init];
[self presentViewController:myVc animated:YES completion:nil];
This will obviously present a new blank view controller, if you want your PageID view then you replace UIViewController with the name of the PageID class (i,e the .h/.m file names)
So i'm assuming this:
PageID *myVc = [[PageID alloc] init];
[self presentViewController:myVc animated:YES completion:nil];
If you want it inside a navigation controller do:
PageID *myVc = [[PageID alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:myVc];
[self presentViewController: navController animated:YES completion:nil];
OR if you don't want it to be modal (don't need to create a new navigation controller as it will be added to the existing navigation controller stack i.e. [self navigationController]:
[[self navigationController] pushViewController:myVc animated:YES];

Resources