How to remove the back arrow ios 7 navigation bar? - ios7

In my custom navigation bar, i want to use hide default back button and use my customize left button, but even if the back button is hidden, it sill take some space at the left end of navigation bar.
How to get rid of back arrow button completely?
I have tried to set backBarButtonItem and 'hidesBackButtonproperties ofUINavigationItem`, but none of these works.
UPDATED:
- (void) viewDidLoad{
//...
self.navigationItem.hidesBackButton = YES;
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:_backButtonView];
//...
}
I use Spark Inspector to inspect the view hierarchy.
As you see, the back arrow button still takes some space in navigation bar.
UPDATED:
The back arrow is actually an instance of _UINavigationBarBackIndicatorView, it look like a private class.
UPDATED:
It turns out the problem have nothing to do with the UINavigationbarBackIndicatorView. iOS 7 will add spacing before the left item.
this problem is similar to this. Found the answer.

You should set hidesBackButton to YES before you push the controller. That is the navigation controller should be set hidebackbutton in previous viewcontroller if the pushing view must have hidden back button.
I hope this may help you.

It turns out my problem is similar to this
The solution from that question work for me.

Related

ios7 presentViewController reverts navBar from new 64px bar back to old 44px version

I have an application that is supporting only ios7+ The navbar setup is using the new 64px high bar that appears beneath the status bar. Here is what it looks like when the app launches:
If I do any sort of "presentViewController", when i dismiss the view the navbar shifts back to 44px height and still appears underneath the status bar which in-turn makes all the contents of the view also shift up. Here is what that looks like:
It doesn't matter if I am presenting one of my own views or if I simply present a UIImagePickerView, any sort of slide up modal via the navigation controller breaks the navbar setup. Any ideas on how to fix this?
A few notes:
in plist: "View controller-based status bar appearance" is set to "NO"
navbar configured with self.navController.navigationBar.translucent = NO;
I am using .xib NOT Storyboards
UPDATE:
I have the navigation controller inside of a PKRevealController (https://github.com/pkluz/PKRevealController). Taking the reveal controller out and just adding the nav controller to the window itself fixes the issue... why would the reveal controller cause it to behave differently?
SOLUTION:
It turned out that the PKRevealController library was causing the issue. I reworked how it was set up in the AppDelegate and that solved the problem, although it's sorta of "hacky". I put my "before" and "after" configurations below:
the initial setup was :
configure PKRevealController
configure NavController and add rootView
set pkreveal front view = navController
add reveal controller to window as windows root view
the fix is
create a containing NavController
do stpes 1-3 above
add pkrevealcontroller to the containing navController
set containing nav controller nav bar to hidden
add containing nav controller to window as root view
If its navigationcontroller than you can use this inside every viewcontroller's viewdidload:
if ([self respondsToSelector:#selector(edgesForExtendedLayout)]) {
self.edgesForExtendedLayout = UIRectEdgeNone;
}
I had the same problem, but solved very easily by just setting the UINavigationBar Y-position to 20px and not to 0px. Then you have to assign the UINavigationBarDelegate to your ViewController:
[_navigationBar setDelegate:self];
Furthermore you have to add this method to your ViewController, which will be called because of the Delegate assignment:
-(UIBarPosition)positionForBar:(id<UIBarPositioning>)bar
{
return UIBarPositionTopAttached;
}

iOS non-navigation bar based navigation and view swapping

I'd like to create an app without using the fancy iOS navigation bar. What's the best or most correct way to change between full screens?
So say I start on "Home", and I want to go to "LogIn" without using the navigation bar -- what should I do? Should I change rootViewController? And when I swap in the new view, how do I make sure the old view is completely released? I imagine with ARC if there's no references it will merely disappear? And pre-ARC I have to set everything to null?
Or is the correct way to hide the navigation bar and use its stack?
Thanks!
Use the normal UINavigationController and set the navigation bar to hidden. Quite easy.
You can't use the default UINavigationController with the default segues if you don't want a stack. If you want all the views behind the destination to be released they have to be removed from the stack as the destination goes on screen.
My answer would be to put everything in a navigation controller, set the bar to hidden (self.navigationController.navigationBarHidden = YES;) and create a custom segue that overrides the perform method like this:
- (void) perform {
UIViewController* destination = self.destinationViewController;
NSArray* newStack = [NSArray arrayWithObject:destination];
UIViewController* source = self.sourceViewController;
[source.navigationController setViewControllers: newStack animated: YES];
}
Then, wire everything up like normal and make the segues your custom class. That way any time you segue the stack will be cleared of everything but the newly visible controller.
EDIT: I'm guessing you edited to clarify that you wanted to use that stack whilst I was writing this. Oh, well. In that case, yeah, just set the bar to hidden and use like normal.

Is there a way to select a segue anchor programmatically?

Suppose I have a Storyboard containing a view that contains a button. When the user presses this button, a popover comes up.
Thus, I need to set an anchor by dragging the segue to the button using Xcode (and then do performSegueWithIdentifier:).
So, my question is: is there a way to set this "anchor" programmatically?
Thank you.
In my case I've added programmatically several UIBarButtonItem.
The problem of only using an invisible view as an archor is that, if like in my case, the size of the UIBarButtonItem is changing it's size, the arrow of the popover doesnt appear centered, and althought it works, looks a bit strange.
How to solve it.
Create a small view in storyboard ( the size doesnt really matter ), make it invisible, and link it.
In my case this is called invisibleViewAsArchor
Connect the UIBarbutton item with the follow action.
-(IBAction) showMyPopover:(id)sender {
if([self.popoverController isPopoverVisible])
{
[self.popoverController dismissPopoverAnimated:YES];
}else{
self.invisibleViewAsArchor.frame = CGRectMake([sender view].frame.origin.x,
[sender view].frame.origin.y-50,
[sender view].frame.size.width,
[sender view].frame.size.height);
[self performSegueWithIdentifier:#"segue_to_something" sender:self];
}
}
as you can see before it shows the popover (with performSegueWithIdentifier), I'm changing the frame
of the Archor with the values from the button that has fired the event.
Hope it helps.
In the storyboard anchor the popover to some arbitrary button. Don't worry too much about which one as it will get overridden in the code.
In the view controller method prepareForSegue, add the code:
let dest = segue.destinationViewController
dest.popoverPresentationController?.barButtonItem = <your bar button here>
or if you want to anchor to a view instead
dest.popoverPresentationController?.barButtonItem = nil
dest.popoverPresentationController?.sourceView = <your view here>
You can't programmatically create segue's as explained here: Creating a segue programmatically, however, you can configure which destination controller you want to display at run-time. This is explained in the apple documentation here: Configuring the Destination Controller When a Segue is Triggered.
Hopefully this helps!
I had the same problem where I was creating a BarButtonItem programmatically. You may also be able to get around it by creating an invisible, disabled button which you can set as the anchor in IB.

UISearchBar in UINavigationController with cancel button not selectable

I have added a UISearchBar to the UINavigationController just fine, but as soon as I add the cancel button to the search bar I can no longer select it by touching it.
The code I'm using to create the search bar and add it is:
UISearchBar *theSearchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0.0f,0.0f,320.0f,0.0f)];
theSearchBar.delegate = self;
[theSearchBar setPlaceholder:#"Search iPad"];
[theSearchBar setShowsCancelButton:YES animated:YES];
self.navigationItem.titleView = theSearchBar;
self.navigationItem.titleView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[theSearchBar release];
If I remove the line to add the cancel button I'm able to focus on the search bar and the search works correctly. As soon as I put that line in, it displays properly, but I can no longer focus on it.
I've tried putting it into a simple UIView container, but that didn't solve the problem either.
What about adding the cancel button could be causing this to fail?
UPDATE:
I ended up not using the cancel button because I determined it wasn't necessary the way the search bar was being used.
I would definitely recommend a UISearchDisplayController: apple docs.
It has a cancel button built right in, and by placing it in interface builder you can save a lot of code. Less code = less bugs.

Adding a Navigation Controller to a View based Application adds top margin

I am trying to programmatically add a Navigation Controller to my View based Application. This is the code I am using (this code gets called after a button press in a view controller):
MainMenu *control = [[MainMenu alloc] initWithNibName: #"MainMenu" bundle: nil];
UINavigationController *navControl = [[UINavigationController alloc] initWithRootViewController: control];
[self.view addSubview:navControl.view];
[control release];
That works, but this ends up happening:
Notice the odd margin above the Navigation control.... My View controller that I am adding the Navigation Controller to has a gray background which you can see.
Any ideas??
If you have a better way of adding a Navigation Controller to a View based Application I am very open to suggestions!
Thank you in advance!
Thank you both for your response, but unfortunately, wantsFullScreenLayout set to YES or NO in the code didn't have any effect. I was able to push the Navigation Controller up by 20 using this line of code:
self.navigationController.navigationBar.frame = CGRectOffset(self.navigationController.navigationBar.frame, 0.0, -20.0);
but then what happened was that the View Controller did not move up with the Navigation bar and left a gap below the Navigation Bar and the View Controller. What eventually worked was checking the Wants Full Screen checkbox in IB in the MainWindow view controller that is automatically generated when you set up a view based application.
The gap you are seeing is the same height as a status bar. Check the status bar settings in your NIB file.
Chances are you want to make the UINavigationController the root view controller for the window, rather than whichever view controller you have now. That would be the better way to do it.
The reason you're seeing that extra margin at the top is because UINavigationController normally expects that it will be sized to fill the entire screen (except perhaps a tab bar at the bottom, if it's inside a UITabBarController), and therefore expects that the top edge of its view will be under the status bar if the status bar is visible. Therefore, it places its navigation bar 20 pixels below the top of its view to leave space for the status bar, without bothering to check whether its view actually is under the status bar. Interestingly, sometimes a re-layout operation will perform this check, but that's unreliable. What I've found works well in a situation like this is to set the UINavigationController's wantsFullScreenLayout property to NO. Then ti doesn't try to leave room for the status bar, so everything works as expected.
I've been struggling with this same issue this morning. Since setting the wantsFullScreenLayout property doesn't seem to have any effect, I resorted to using a little subclass, which worked fine:
#interface MyNavigationController : UINavigationController
#end
#implementation MyNavigationController
- (BOOL)wantsFullScreenLayout;
{
return NO;
}
#end
Its so simple to remove that gap..
self.navigationBar.view.frame = CGRectMake(0, -20, 320, 480);