How to present a Tab Bar Controller from a UI View Controller - ios

This is the situation...
I have UIViewController, I want to programatically, without any buttons, to go to my Tab Bar Controller or to one of my Table View Controllers.
This is what I did so far:
UIViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
[self dismissViewControllerAnimated:NO completion:^{
[self performSegueWithIdentifier:#"appLaunched" sender:self];}];
}
This does not work, I made a segue and gave it an id, but the issue remains, my app when launches just shows a white screen and the transition is never made. Can anyone help me please?
Thank you.

Perhaps try something like
- (void)viewDidLoad
{
[super viewDidLoad];
[self pushIt];
}
- (void)pushIt
{
[self.navigationController pushViewController:[self.storyboard instantiateViewControllerWithIdentifier:#"appLaunched"] animated:YES];
}

Related

Push / Pop View Controller With Navigation Bar from View Controller Without Navigation Bar

I'm trying to push a view controller with a visible navigation bar from a view controller with a hidden navigation bar.
I tried all sorts of combinations of [[self navigationController] setNavigationBarHidden:YES animated:NO]; in viewWillAppear, viewDidAppear, viewWillDisappear... etc.
// First View Controller
#implementation FirstViewController
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[self navigationController] setNavigationBarHidden:YES animated:NO];
NSLog(#"[%# viewWillAppear]", self);
}
#end
// Second View Controller
#implementation SecondViewController
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[self navigationController] setNavigationBarHidden:NO animated:NO];
NSLog(#"[%# viewWillAppear]", self);
}
#end
Nothing worked. I also tried custom code to "animate" a push and pop, which works, BUT I lose the edge swipe and view panning. Before I dig deeper, just want to make sure I'm not reinventing the wheel.
The Starbucks app is what I'm trying to mimic.
The root view controller of the app (the dark background view) is full screen and notice how it doesn't have a UINavigationBar. But when you tap on one of the buttons, it pushes on a view controller (the light background view) WITH a UINavigationBar. From there, if you tap the "back" arrow, it view controller pops with the navigation bar. Interactive pop swipe gesture also works.
It is possible without hacking together a solution by yourself. Here is what you do:
Your root viewController:
#implementation ViewController
....
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:YES animated:animated];
}
#end
And the pushed viewController:
#implementation SecondViewController
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:NO animated:animated];
}
#end
This will do. It also keeps the interactive transition working ;)
I find it disturbing, however, that this type of functionality is not documented at all by apple. - You can also hide and show toolbars with these 'call-points' (inside viewWillAppear:)
EDIT
I just realized that this is the same code you wrote in your question. Please test it again. I am 100% sure that this works - I used this functionality in one of my apps, too.
Please also note that my code does use animated:animated instead of your animated:NO. This may be the crucial point here :)
I just set up two view controllers to test this back and forth.
#interface VC1 ()
#end
#implementation VC1
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.navigationController.navigationBarHidden = YES;
}
#end
and a second
#import "ViewControllerTwo.h"
#interface ViewControllerTwo ()
#end
#implementation ViewControllerTwo
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.navigationController.navigationBarHidden = NO;
}
#end
VC1 is embedded in a navigationController (which is the root controller for the app), with a button that navigates to ViewControllerTwo. I have a push segue from VC1 -> ViewControllerTwo, this method works. When I tap on the button, the view controller is visible on ViewControllerTwo, when I press back, the navigationBar is gone.

Change back to ViewController after certain time interval

I am trying to create an app that has a navigation bar at the bottom of the first view controller. When the user presses next they are taken to the second view controller in the storyboard. I would like to know if it is possible to make the program automatically take the user back to the first view controller after 10 seconds? I am very new to xcode so any help implementing this in a simple fashion would be greatly appreciated
just create a function and call that after time delay and push in that
in second viecontroller
- (void)viewDidLoad
{
[super viewDidLoad];
[self performSelector:#selector(yourMethod) withObject:nil afterDelay:10.0];
}
-(void)yourMethod
{
//[self.navigationController popViewControllerAnimated:YES];
[self dismissViewControllerAnimated:YES completion:nil];
}
hope this will help you
Add the below to viewDidLoad in your second view controller
- (void)viewDidLoad {
[super viewDidLoad];
[self performSelector:#selector(viewWillDisappear:) withObject:nil afterDelay:2.0];
//I have given 2 seconds. you can change as your wish
}
Add this method too below.
-(void) viewWillDisappear:(BOOL)animated{
[self dismissViewControllerAnimated:YES completion:nil];
}
Hope it works..

NavigationBar Hidding issue on Back

On View1 I hide the navigationBar in viewDidLoad:
- (void)viewDidLoad
{
[super viewDidLoad];
[self.navigationController setNavigationBarHidden:YES];
}
Then I navigate to View2 where I show the navigationBar
- (void)viewDidLoad
{
[super viewDidLoad];
[self.navigationController setNavigationBarHidden:NO];
self.title = #"Title";
}
But on back to View1 again, the navigationBar doesn't hide, even if I did tried to hide it after the pushViewController in View2
[self.navigationController pushViewController:View1 animated:YES];
[self.navigationController setNavigationBarHidden:YES];
I also tried to hide the navigation from viewWillAppear in View1 and it hides it, but there is an ugly delay and I don't find it as a good practice.
So can anyone help me with this issue, how can I hide correctly the navigationBar on back to View1?
The best practice to do what you want is putting bellow in your first viewController:
- (void)viewWillAppear:(BOOL)animated{
[self.navigationController setNavigationBarHidden:YES animated:animated];
[super viewWillAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated{
[self.navigationController setNavigationBarHidden:NO animated:animated];
[super viewWillDisappear:animated];
}
-(void) viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self.navigationController setNavigationBarHidden:YES];
}
The ViewController1 is not going to get allocated again and so viewDidLoad is not going to get called.
You can do it in viewWillAppear though. But if you are saying that there is a delay, you can do one more thing.
You can get the reference ofViewController1 in ViewController2. Suppose ViewController1 is the first controller in the navigation controller, then do this:
//ViewController2.m
- (IBAction)backButtonPressed:(id)sender{
ViewController1 *view1 = [self.navigationController.viewControllers objectAtIndex:0];
[view1.navigationController setNavigationBarHidden:YES];
Your code is correct, but you need to write like this:
[self.navigationController setNavigationBarHidden:YES];
first, then write
[self.navigationController pushViewController:View1 animated:YES];
See when you are pushing View2 from View2 in navigation stack than View1 doesn't gets deallocated. it is there in in the stack. So when you popping out View2 that time View1 viewDidLoad won't get called. so your code setNavigationBarHidden to hide navigation bar doesn't executes. So put that code to ViewWillAppear or ViewDidAppear because these methods gets called every time View appears.
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:YES];
}

UIViewController pushViewController, show navigationBar

I have UIViewController(1) without navigationBar, and I need to push anouther UIViewController(2) that have navigationBar, and when I click Back on it, navigationBar must hide on 1 controller. I have tried uiviewcontroller delegates.
But nothing is working..
Please help..
This will show the navbar on the second screen:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.navigationController.navigationBarHidden = NO;
}
You will also need to hide the navbar when you return to the first screen:
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
self.navigationController.navigationBarHidden = YES;
}
I think you want the animated option. If you roll with the approaches above (self.navigationController.navigationBarHidden = value) you get some undesirable visual crumbs.
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:NO animated:YES];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[self.navigationController setNavigationBarHidden:YES animated:YES];
}
This will push/pop smoothly with the navBar firmly attached to the appearing/disappearing view.
Place this code in first view controller
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.navigationController.navigationBarHidden = YES;
}
Answers from Alfie or Ader would be a disaster if you have many viewcontrollers' navigation bar hidden/show state to manage.
I just have posted code dedicated on UINavigationBar appearance management on github. check out RRViewControllerExtension, it will solve your problem gracefully.
With RRViewControllerExtension, you even don't have to #import the header file, all you have to do is just override any desired method below in your viewcontroller.
//override any of the methods below in your viewcontroller's .m file to make specific navigation bar appearance
-(BOOL)prefersNavigationBarHidden;
-(BOOL)prefersNavigationBarTransparent;
-(nullable UIColor *)preferredNavatationBarColor;
-(nullable UIColor *)preferredNavigationItemColor;
-(nullable UIImage *)preferredNavigationBarBackgroundImage;
-(nullable NSDictionary *)preferredNavigationTitleTextAttributes;

pushViewController followed by 'back' button sometimes doesn't pop view

I am using pushViewController to push a view in my application. Pressing the back button works about 95% of the time like you would expect. But if I go in and out of the view as fast as possible I run into a condition where the top bar moves as if a pop has occurred, but the view says. In this state, I am left with a back button, (in normal operation I have changed the text of this button to 'cancel'). pressing back will animate the top bar again, and then I am left with no buttons in the top bar, and I'm stuck inside the view.
Do you have any idea what might be going on here? Here are some more details:
The sub view calls these once or twice:
[[UIApplication sharedApplication] beginIgnoringInteractionEvents];
[[UIApplication sharedApplication] endIgnoringInteractionEvents];
also the sub view is extending a BaseViewController. Inside this base controller all of the view methods are overloaded (they just call super). The one that might be interesting is:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self customizeNavigationBar];
}
- (void)customizeNavigationBar
{
[self.navigationController.navigationBar setTintColor:UIColorFromRGB(kNavigationBackgroundColor)];
UIBarButtonItem *backButton_ = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(#"ID_BUTTON_BACK", #"") style:UIBarButtonItemStyleBordered target:self action:nil];
self.navigationItem.backBarButtonItem = backButton_;
[backButton_ release];
}
Please let me know if you need more code or if I can explain things better.
--- Edit ----
I also am calling Google Analytics in view will appear. I remember this causing other issues in my app:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
NSError *error;
if (![[GANTracker sharedTracker] trackPageview:#"/app_new_page"
withError:&error]) { }
}
This code is being put in my actual view (not BaseViewController).
I found the problem. The issue was that I was calling setNavigationBarHidden:NO with animated:NO in viewDidLoad to show the nav bar without animation, but using pushViewContoller with animated:YES.
----- originally -----
[self.navigationController pushViewController:controller animated:YES];
and
- (void)viewDidLoad
{
[super viewDidLoad];
[self.navigationController setNavigationBarHidden:NO animated:NO];
}
The solution was to remove setNavigationBarHidden from viewDidLoad and move it into viewWillAppear, and to animate it the same way the view was animated. Since my nav bar was appearing instantly, it was possible to press back before the view controller had finished animating (pushing onto the stack), causing all these issues.
----- solution -----
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:NO animated:animated];
}
Thanks for your help guys!

Resources