Navigation bar not appearing when pushing a controller from a presented ViewController - ios

I have following code to present a UIViewController (named A) with UINavigationController.
I have kept navigation bar hidden as I do not want it on A by using following code
[self.navigationController.navigationBar setHidden:YES];
but when I push UIViewController named B I want the navigation bar to be displayed but it's not working even If set
self.navigationController?.setNavigationBarHidden(false, animated: false)
on UIViewController B. Can someone help me in this?
Here is the code to present UIViewController A
AppDelegate* delegate = [AppDelegate applicationDelegate];
UIStoryboard *story = [UIStoryboard storyboardWithName:STORYBOARD_MAIN bundle:nil];
SelectionViewController *tutorial = [story instantiateViewControllerWithIdentifier:#"SelectionViewController"];
tutorial.providesPresentationContextTransitionStyle = YES;
tutorial.definesPresentationContext = YES;
[tutorial setModalPresentationStyle:UIModalPresentationOverCurrentContext];
tutorial.delegate = self;
UINavigationController* navController = [[UINavigationController alloc] initWithRootViewController:tutorial];
navController.modalPresentationStyle = UIModalPresentationFullScreen;
[navController.navigationBar setHidden:YES];
navController.providesPresentationContextTransitionStyle = YES;
navController.definesPresentationContext = YES;
[navController setModalPresentationStyle:UIModalPresentationOverCurrentContext];
[delegate.tabBarController presentViewController:navController animated:YES completion:NULL];
Here is the code to push UIViewController B
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"AppDetail" bundle:nil];
DetailViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"DetailViewController"];
[self.navigationController pushViewController:vc animated:YES];
[[self navigationController] setNavigationBarHidden:NO];
Additional information
UIViewController A is in different storyboard and B is in different
A's code is written in OBJ-C and B's code is in swift.

Related

Push view controller not working

I'm using UINavigation and UIPageView controller in a UIViewController. I have 3 buttons and here is my code :
- (IBAction)StartButtonClicked:(id)sender {
NSLog(#"start button pressed");
[_Timer invalidate];
_Timer = nil;
dispatch_async(dispatch_get_main_queue(), ^{
UIStoryboard* storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
CardViewController* controller = [storyboard instantiateViewControllerWithIdentifier:#"CardViewController"];
[self.navigationController pushViewController:controller animated:NO];
}
}
- (void)pageViewController {
self.pvc = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
self.pvc.view.frame = self.view.bounds;
[self.view addSubview:self.pvc.view];
[self.pvc setViewControllers:#[[viewControllerArray1 objectAtIndex:0]] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil];
}
- (IBAction)rightButtonPressed:(id)sender {
[self pageViewController];
[self.pvc setViewControllers:#[[viewControllerArray1 objectAtIndex:1]] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil];
}
- (IBAction)leftButtonPressed:(id)sender {
[self pageViewController];
[self.pvc setViewControllers:#[[viewControllerArray1 objectAtIndex:2]] direction:UIPageViewControllerNavigationDirectionReverse animated:YES completion:nil];
}
When I click on right button and came back to this view controller my start button's push view not working.
Please check the answer .
iOS - Push viewController from code and storyboard
Don't initialize Storyboard always,
UIStoryboard* storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
You can set the rootViewController from the UtoryBoard itself.
Set initialViewController as a UINavigationController and Set the FirstViewController as RootViewController.
Edit :
For Push use the below code,
CardViewController* controller = [storyboard instantiateViewControllerWithIdentifier:#"CardViewController"];
[self.navigationController pushViewController:controller animated:NO];
and Back. If use the default backButton not need to write any code.
If use are using custom backButton,
[self.navigationController popViewController];
Check 2 things,
Your storyboard identifier is correct.
The root view have navigation Controller.
Your StoryBoard should be like this,

iOS - some questions about present and push the controllers

There are three controllers here, AViewController, BViewController, CViewController,
the first step: AViewController present to BViewController;
BViewController *BVC = [[BViewController alloc]init];
[self presentViewController:BVC animated:YES completion:nil];
The second step: BViewController push to CViewController;
CViewController *CVC = [[CViewController alloc]init];
UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:CVC];
[self.navigationController pushViewController:nav animated:YES];
Now, if I want to go back from CViewController to AViewController, what code should I write?
Just use this code:
self.dismissViewControllerAnimated(true, completion: nil)
to dismiss C ViewController, because C ViewController is now on the Navigation Stack. A present a navigation controller that contain B ViewController. B ViewController push C ViewController, so C is still in Navigation Controller.
You can look at my project here:
https://github.com/khuong291/TestTransition
You should present BViewController like this:
BViewController *BVC = [[BViewController alloc]init];
UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:BVC];
//Setting For Transparent
nav.providesPresentationContextTransitionStyle = YES;
nav.definesPresentationContext = YES;
nav.modalPresentationStyle = UIModalPresentationOverCurrentContext;
[self presentViewController:nav animated:YES completion:nil];
and in BViewController implement:
- (void)viewWillDisappear:(BOOL)animated {
[self.navigationController setNavigationBarHidden:YES];
}
- (void)viewWillDisappear:(BOOL)animated{
[self.navigationController setNavigationBarHidden:NO];
}
And you can push to CViewController:
CViewController *CVC = [[CViewController alloc]init];
[self.navigationController pushViewController:CVC animated:YES];
And when you want back to A. Simple call it in C:
[self dismissViewControllerAnimated:YES completion:nil];

Push View from Presented View Controller in iOS

In Short :
How can I PushViewController from Presented ViewController ?
In Brief :
I have MainViewController, In which I have one button on click of button, I am presenting a view called LoginViewController.
On this page (LoginViewController), I again have button, on click of that, I try to push my view controller(called HomeViewController) it doesn't pushes.
Here is my code snippet,
MainViewController.m
- (IBAction)LoginClicked:(id)sender {
LoginViewController *vc = [[LoginViewController alloc] init];
[self presentViewController:vc animated:YES completion:nil];
}
LoginViewController.m
- (IBAction)buttonActionMethodOnLoginView:(id)sender{
NSLog(#"viewControllers %#",APPDELEGATE.nav.viewControllers);
//LoginViewController is not in this array
HomeViewController *obj = [[HomeViewController alloc] init];
[self.navigationController pushViewController:obj animated:YES];
}
But it did not works for me. Also, I printed a stack of view controllers before pushed, but it doesn't have LoginViewController. So, without adding LoginViewController into a stack of view controllers, How can I pushed to HomeViewController from LoginViewController ?
When I getBack from HomeViewController, then LoginViewController should get opened..
Is it possible using doing this single NavigationController?
Note:- Here, I have just taken an example using Login, Home and Main ViewController. But I want that into Other Screens.
hi when you are Presenting you Login view controller Just present a navigationController like:
LoginVC *loginVCObj =[[LoginVC alloc]initWithNibName:#"LoginVC" bundle:nil];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:loginVCObj];
[self presentViewController:nav animated:YES completion:nil];
Now your PresentedViewController is An navigtioncontroller
now you can simply push to your Home VC
HomeViewController *obj = [[HomeViewController alloc] init];
[self.navigationController pushViewController:obj animated:YES];
Hope it will helpful for you
LoginViewController should not be pushed to navigation controller stack. Let me describe below "why".
Our MainViewController should be on the stack - you always want to go back there.
// AppDelegate.m (only if you don't use storyboards, if you do - you don't need to copy this part of code)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// create the window
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window setBackgroundColor:[UIColor whiteColor]];
[self.window makeKeyAndVisible];
// set view controllers
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:[[MainViewController alloc] init]];
[self.window setRootViewController:navigationController];
}
On specific action show LoginViewController. You don't want the user to be able to tap back and go to MainViewController. Later, you won't want user to go back to LoginViewController. Because of this, you need to present it as modal:
// inside `MainViewController.m`
- (IBAction)myCoolActionToShowLogin:(id)sender {
[self presentViewController:[[LoginViewController alloc] init] animated:YES completion:nil];
}
Now we can see LoginViewController. When user completes the login, dismiss it and present HomeViewController:
// inside `LoginViewController.m`
- (IBAction)myAwesomeActionToShowHome:(id)sender {
UINavigationController *navigationController = (UINavigationController *)[UIApplication.sharedApplication.keyWindow rootViewController];
[navigationController pushViewController:[[HomeViewController alloc] init] animated:YES];
[self dismissViewControllerAnimated:YES completion:nil];
}
NOTES:
As you may notice, myAwesomeActionToShowHome: expects you have navigation controller as your rootViewController. This is working, but should be nicer - you should check if that navigation is in fact navigation controller instead of casting it. Or you may create a delegate or block to push new one. This is the fastest, easiest working solution, which should be improved later.
You really should read: Apple Developer -> "View Controller Programming" documentation, as these are the core fundamentals you should know to develop & design UX correctly.
Here is the working demo sample.
You can't push from a presented view controller. I suggest, you should maintain your navigation hierarchy.
For that, from your MainViewController, you should present LoginViewController and you should pass navigation controller for the MainViewController.
- (IBAction)openLogin:(id)sender {
LoginViewController *loginVC = (LoginViewController *) [self.storyboard instantiateViewControllerWithIdentifier:#"login"];
[loginVC setReferencedNavigation:self.navigationController];
[self presentViewController:loginVC animated:YES completion:nil];
}
Then inside LoginViewController, you should push to HomeViewController like this,
LoginViewController.h
#interface LoginViewController : UIViewController {
UINavigationController *refNavigationController;
}
- (void) setReferencedNavigation:(UINavigationController *)refNavCon;
LoginViewController.m
- (void) setReferencedNavigation:(UINavigationController *)refNavCon {
refNavigationController = refNavCon;
}
- (IBAction)openHome:(id)sender {
[self dismissViewControllerAnimated:YES completion:^{
UIViewController *homeVC = [self.storyboard instantiateViewControllerWithIdentifier:#"home"];
[refNavigationController pushViewController:homeVC animated:YES];
}];
}
By doing this, it will be look like, you're pushing from LoginViewController but in reality you're pushing from MainViewController.
You can customize this approach to maintain animation and UI for this flow.
1) present a navigation controller with itsroot view controller` set as view controller .
- (IBAction)LoginClicked:(id)sender
{
LoginViewController *loginViewController = [LoginViewController alloc] init];
UINavigationController *navController = [UINavigationController alloc] initWithRootViewController:loginViewController];
[self presentViewController:navController animated:YES completion:nil];
}
- (IBAction)buttonActionMethodOnLoginView:(id)sender
{
HomeViewController *obj = [[HomeViewController alloc] init];
[self.navigationController pushViewController:obj animated:YES];
}
Hope it will work for you.
The problem is that LoginViewController has no navigation controller. Then you give it one.
MainViewController.m
Create a UINavigationController, put LoginViewController in to the stack and present the UINavigationController.
- (IBAction)LoginClicked:(id)sender {
LoginViewController *vc = [[LoginViewController alloc] init];
UINavigationController = nav = [[UINavigationController alloc] init];
nav.viewControllers = #[vc];
[self presentViewController:nav animated:YES completion:nil];
}
LoginViewController.m
- (IBAction)buttonActionMethodOnLoginView:(id)sender{
HomeViewController *obj = [[HomeViewController alloc] init];
[self.navigationController pushViewController:obj animated:YES];
}
Dismiss
Call dismissViewControllerAnimated in your MainViewController.
For Swift 3.0
Present your view controller as a new rootViewController
let navController = UINavigationController.init(rootViewController: self.storyboard!.instantiateViewController(withIdentifier: "SignInViewController"))
self.present(navController, animated: true, completion: {})
Now push your view controller from presented view controller
self.show(self.storyboard!.instantiateViewController(withIdentifier: "SignUpViewController"), sender: self)
Create a UINavigationController instance
[[UINavigationController alloc] initWithRootViewController:[[LoginViewController alloc] init]]
Present that navigationController and then push whatever VC you want to.
MainViewController.m
- (IBAction)LoginClicked:(id)sender {
LoginViewController *vc = [[LoginViewController alloc] init];
UINavigationController *loginNav = [[UINavigationController alloc] initWithRootViewController:vc];
[self presentViewController:loginNav animated:YES completion:nil];
}
LoginViewController.m
- (IBAction)buttonActionMethodOnLoginView:(id)sender{
NSLog(#"viewControllers %#",APPDELEGATE.nav.viewControllers);
//LoginViewController is not in this array
HomeViewController *obj = [[HomeViewController alloc] init];
[self.navigationController pushViewController:obj animated:YES];
}
You have to Push from your firstView (MainViewController), but you can use animation same as PresentView and DismissView. Use following code for this :-
For Push (on MainViewController)
LoginViewController *VC = [[LoginViewController alloc]init];
CATransition* transition = [CATransition animation];
transition.duration = 0.3f;
transition.type = kCATransitionMoveIn;
transition.subtype = kCATransitionFromTop;
[self.navigationController.view.layer addAnimation:transition
forKey:kCATransition];
[[[UINavigationController alloc] initWithRootViewController:VC] pushViewController:VC animated:NO];
//[self.navigationController pushViewController:VC animated:NO];
For Pop (on LoginViewController)
CATransition* transition = [CATransition animation];
transition.duration = 0.3f;
transition.type = kCATransitionReveal;
transition.subtype = kCATransitionFromBottom;
[self.navigationController.view.layer addAnimation:transition
forKey:kCATransition];
[self.navigationController popViewControllerAnimated:NO];
Using this code, you can get animation same as Present-Dismiss ViewControllers. Refer this answer for more details.
And after that, you can use your code for Pushing LoginViewController to HomeViewController
Hope, this is what you're looking for. Any concern get back to me. :)
This is very simple code for present view controller and push view controller.
- (IBAction)LoginClicked:(id)sender {
LoginViewController *objLogicVC = [LoginViewController alloc] init];
UINavigationController *navPresent = [UINavigationController alloc] initWithRootViewController:objLogicVC];
[self presentViewController:navPresent animated:YES completion:nil];
}
- (IBAction)buttonActionMethodOnLoginView:(id)sender{
HomeViewController *objHomeVC = [[HomeViewController alloc] init];
[self.navigationController pushViewController:objHomeVC animated:YES];
}
simply put this code in objective c on button action
UIViewController *yourViewControllerName = [self.storyboard instantiateViewControllerWithIdentifier:#"yourViewControllerName "];
[[self navigationController] pushViewController:yourViewControllerName animated:YES];

Back button from xib to storyboard

Currently I develop with a StoryBoard for the iPad. Additionally I add a ViewController.xib file with a view. Now I want to back button from xib to storyboard. My code is below but this is not working.
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UIViewController *initViewController = [storyBoard instantiateInitialViewController];
[self.navigationController pushViewController:initViewController animated:YES];
You can present the View Controller from a storyboard scene, using
- presentViewController:animated:completion: (e.g. for a modally scenario)
ViewController *vc= [[ViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:vc];
[self presentViewController:navController animated:YES completion:NULL];
then, you can add a custom back button
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(#"Back", #"Back from ViewController.XIB") style:UIBarButtonItemStylePlain target:self action:#selector(backAction:)];
self.navigationItem.leftBarButtonItem = backButton;
and dismiss it:
- (void)backAction:(id)sender{
[self.presentingViewController dismissViewControllerAnimated:YES completion:NULL];
}
Forget about the navigationController.
In your active view controller init the new view controller like this.
UIViewController *initViewController = [[UIViewController alloc]
initWithNibName:#"YourNibFile" bundle:[NSBundle mainBundle]];
[self presentViewController:initViewController animated:YES completion:nil];
And to dismiss.
[self dismissViewControllerAnimated:self completion:nil];

Push action for UIPopOverController

I created a pop over to view my settings like this,
if ([popoverController isPopoverVisible]) {
[popoverController
dismissPopoverAnimated:YES];
} else {
UIView* popoverView = [[UIView alloc]
initWithFrame:CGRectMake(566, 440, 0, 0)];
popoverView.backgroundColor = [UIColor blackColor];
controller1.contentSizeForViewInPopover = CGSizeMake(300, 115);
popoverController = [[UIPopoverController alloc]
initWithContentViewController:controller1];
[popoverController presentPopoverFromRect:popoverView.frame
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionUp
animated:YES];
}
my push action code:
UIStoryboard *storyboard = [UIStoryboard
storyboardWithName:#"MainStoryboard"
bundle:nil];
UIViewController *controller = (UIViewController *)[storyboard
instantiateViewControllerWithIdentifier:#"PCBViewController"];
[self.navigationController
pushViewController:controller
animated:YES];
In my settings popover has some buttons. Those button is clicked, view controller open through push action but its not working.
My Question is: How to set push action for popover contents.
Your view is presented from popover thus self.navigationController will be nil.
Try this
UIStoryboard *storyboard = [UIStoryboard
storyboardWithName:#"MainStoryboard"
bundle:nil];
UIViewController *controller = (UIViewController *)[storyboard
instantiateViewControllerWithIdentifier:#"PCBViewController"];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:controller];
[navigationController
pushViewController:controller
animated:YES];
you need to set up navigation controller for the view controller to allow navigation.
in your .h file
UINavigationController *navevent;
UIViewController *yourViewController
in .m file synthasize it and in view did load
navevent=[[UINavigationController alloc]initWithRootViewController:yourViewController];
yourViewController=[[UIViewController alloc]init];
then create your popover like this
yourViewController.view = yourView;
self.popoverController = [[UIPopoverController alloc]initWithContentViewController:navevent] ;
hope this help

Resources