How to handle backBarButtonItem pressed? - ios

I have almost done this in all the application but I have 3 views stacked in navigationController and I need to jump from the third view to the first view.
As I understand I can do this via viewWillDisappear only. But if I try this "jump" I will get the navigationController panel from the second View which with a navigation buttons which cause exceptions/errors.
P.S. Do not advice me to make leftBarButtonitem looking like backBarButtonItem. It is too difficult and I don't know where to find an appropriate image for it.

To my knowledge, you have no choice but to provide your own UIBarButtonItem. You are not permitted from interrupting how UINavigationController works by default. That is, you cannot override the behavior of the back button. You must provide a custom bar button item and set it as the navigation item's left bar button item.
(As a side note, the sort of behavior you're looking for may be an indication of a poor navigation pattern. Back buttons should almost always back out of a navigation hierarchy sequentially.)

Let's say in navigation order your views stacked like top -> 3 -> 2 -> 1 . When you are in this position you can have a flag in your application delegate that shows you will doublePop when backButton pressed as below: ( You are doing this whenever third view appears in the order you mentioned)
MyApplicationDelegate * del = [[UIApplication sharedApplication]delegate];
del.doublePopEnabled = YES;
[del release];
In view 2 :
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
MyApplicationDelegate * del = [[UIApplication sharedApplication]delegate];
if(del.doublePopEnabled){
//Asssuming you have a reference to your navigationController in your view 2
del.doublePopEnabled = NO;
[del.release]
//Use animated as no if you don't want user to see doublePopping.
self.navigationController popViewControllerAnimated:NO];
}
}
Hope it helps.

Related

UIView overlapping Navigation Bar

In a viewController I programmatically create a UIView that has the same height of the screen. The problem is that navigation bar is still visible and clickable, but I want it to go under the new view. How can I do that?
EDIT: this is a screenshot of what I have now
Not sure if this is what you actually want, since hiding it is a quite acceptable thing to do. However you can hide the rightButtonItem and disable the left one:
self.navigationItem.rightBarButtonItem = nil;
self.navigationItem.backBarButtonItem.enabled = NO;
And to get back your right bar button, if you need it again somewhere:
self.navigationItem.rightBarButtonItem = self.*whatever*ButtonItem;
See if that works. I'm away from my Mac at the moment, so can't check it myself.
Right now you have taken navigation controller as a root view
controller (Maybe),In this case navigation controller overlaps the
UIVewController's view that's why it comes on the view so you need to
hide the Navigation controller.
What about making it hidden?
self.navigationController.navigationBarHidden = YES;

iOS - pop a view controller by panning on the left edge, navigation bar disappears

So iOS 7 introduced this new feature that you can pop a view controller by panning on the left edge. Here is my problem: I have two view controllers, A and B, that are connected by a push segue. Both of the controllers have navigation bars (by embedding A in a navigation controller). The navigation bar in B will be hidden once the user enters B's scene, and can be shown if the user taps on the scene. If the user pans on the left edge of B while the navigation bar is hidden, the navigation bar in A will be hidden as well, which means that there is no way for the user to return further back from A. So is there a way to enforce A to always show the navigation bar regardless of B has hidden the bar or not? Or is there a easy way to prevent the pan gesture from taking effect? I read this post which suggested a way of preventing the pan, but I can't locate the property in storyboard.
EDIT: So I disabled the interactive pop gesture recognizer but that only solved half of the problem. The other half is that if I click the back button on the child view controller navigation bar when the navigation bar is disappearing, I am navigated back to the parent view controller without a navigation bar. I tried calling [self.navigationController setNavigationBarHidden:NO] in viewWillAppear and then viewDidLoad but it does not work. Is this some sort of bug in the SDK or am I missing something?
Here is the code for hiding the navigation bar in the child view controller
- (void)hideNavigationBar
{
if (self.navigationBarHidden == NO)
{
[UIView animateWithDuration:UINavigationControllerHideShowBarDuration animations:^{
self.navigationController.navigationBar.alpha = 0.0;
self.previewCollectionView.alpha = 0.0;
} completion:^(BOOL finished) {
self.navigationBarHidden = YES;
}];
}
}
Yes, you can enforce the navigation bar's appearance in the A viewController's -viewWillAppear method.
Also, since you cannot find the interactivePopGestureRecognizer property in the storyboard, you can use this line in the A viewController's -viewDidLoad method:
self.navigationController.interactivePopGestureRecognizer.enabled = NO;
EDIT:
In the viewWillAppear method, you will have to call:
[self.navigationController setNavigationBarHidden:NO];
self.navigationController.navigationBar.alpha = 1.0;
I see a couple problems with your situation:
You disable the interactive pop gesture and you hide the nav bar from view controller B. How is the user supposed to intuitively go back?
The animation that hides your navbar in B may be causing the issue. If it's anything longer than a split second, that animation may not complete in time before you hit the back button and -viewWillAppear fires on A.
Your code in B hides the navigation bar for the navigation controller. The navigation controller that holds view controller A is the same instance that holds view controller B. If you hide the navigation bar when B loads, then you go back to A (not sure how you're doing that without a back button or a edge pan gesture), it should still be hidden.
You probably want NOT disable the gesture (so the user can intuitively go back) and turn the navigation bar back on in view controller A's -viewWillAppear, to cover the case where you turned it off in B:
if (self.navigationBarHidden == NO)
{
self.navigationController.navigationBar.alpha = 1.0;
self.previewCollectionView.alpha = 1.0;
self.navigationBarHidden = NO;
}

UITabBar is removed when pushed back on UITableViewController but not ViewController

I have an iPhone app, which has a UITabBar with 5 tabs in it, each of the 5 tabs have NavigationViewcontroller which push to other "sub" views as the user selects different options.
2 of the tabs are UItableViews and 3 are UIviews.
When I push from a UITableView to another uiview, then return to the original UITableView, the tab bar appears white instead of a is original bar with 5 tbs on it.
However if I do the same thing from one of the 3 UIView (which is are the tab bar) to another UIView, then return the tab bar is as fine.
I am using storyboards (for the second time) and I have checked the Atributes inspector in the navigation controller and the root views for the UIView that are working and the table UITableView that are not and I cannot see any difference.
My question is should they be the same?
I also use this code to try and stop the bar from being hidden in the init method of the first view and the tab view,
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.hidesBottomBarWhenPushed=NO;
}
return self;
Any help or pointers would be greatly appreciated as my reading has left me blank
Use the following way to hide the bottom bar. When pushed it hides the bottom bar and on popping it reveals back the bottom bar
- (void)pushNewViewController{
MyNewViewController *viewController = [self instantiateNewViewController];
viewController.hidesBottomBarWhenPushed = YES;
[self.navigationController pushViewController: viewController animated:YES];
}

TabBar remains hidden despite setting tabbar.hidden = NO in controller

I currently have two view controllers, a CameraViewController that uses the imagePicker to take photos, and a PhotoInboxViewController that shows all the photo messages a person has received. PhotoInboxViewController, as well as my root view controller, is a Tab Bar Controller.
When I present the imagePicker in CameraViewController , as well as the image preview screen that follows it, I disable the TabBar by setting self.tabBarController.tabBar.hidden = YES. My issue is, when PhotoInboxViewController is then shown again (for example, if the user cancels taking a photo), I would want the Tab Bar to be shown again. In my viewWillAppear method in I have the following:
//In PhotoInboxViewController
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if ([[[self tabBarController] tabBar] isHidden]){
self.tabBarController.tabBar.hidden = NO;
}
}
In debugging, I see that the if statement is indeed evaluated as tabBar as isHidden, and therefore the next line is executed as well. However, my Tab Bar remains hidden.
What am I doing incorrectly? Your help is appreciated - thanks!
You shouldn't need to hide the tab bar. When presenting modally you should present from the full screen / root view controller. In this case the tab bar controller, not the view controller 'in' one of the tabs. This allows the presentation to work properly without any strange side effects.

Hide navigationBar?

1) What is the difference between the three lines of code below?
2) Also why does only the third line of code work if I'm returning to a viewController and the previous viewController has set the navigationBar to hidden through the same approach [self.navigationController setNavigationBarHidden:NO] my assumption was that all three lines do the same thing?
self.navigationController.navigationBar.hidden = NO;
[self.navigationController.navigationBar setHidden:NO];
[self.navigationController setNavigationBarHidden:NO];
Follow up:
Why when I need to run this code:
[self.navigationController.navigationBar setBackgroundImage:incorrectAnswerNavigationBarBackgroundImage forBarMetrics:UIBarMetricsDefault];
It only works, working being setting the background image, otherwise the nav bar is just white.
if I have both these lines:
[self.navigationController setNavigationBarHidden:NO];
self.navigationController.navigationBar.hidden = NO;
If I leave out self.navigationController.navigationBar.hidden = NO; the space for the nav bar pops down but it's just white, there is no background image. If I have both lines it works and there is a background image.
The first two are functionally identical; the difference being one uses the dot notation while the other doesn't. These two methods both fire - (void) setHidden:(BOOL)hide on the navigationBar property on the navigation controller.
Now the third one is a completely different method. It's - (void) setNavigationBarHidden:(BOOL)hide and is defined on UINavigationController. The reason why this one works is this method is informing the navigation controller that you wish the navigation bar to be hidden while the first two manually set the navigation bar to be hidden. The first two's changes are undone if UINavigationController calls any methods that modify the hidden property of the navigation bar, hence why the setNavigationBarHidden: method was created so you'd have a way of informing UINavigationController that no matter what it does, it should hide the navigation bar and not change it to be showing.
EDIT: For the second part of this question, you actually need to be calling - (void)setNavigationBarHidden:(BOOL)hidden animated:(BOOL)animated on UINavigationController. That's the proper documented method for UINavigationController.

Resources