iOS non-navigation bar based navigation and view swapping - objective-c

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.

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;
}

Push view to navigation controller from button in other class

I have a UIButton that I create in my sub class ViewController, and add it to my MainViewController.
Now, I added a target method to this button that should push another view controller to my Navigation controller (the one that in the MainViewController).
I know that the method did call when I push the button, but the view wasn't push to the Navigation Controller.
I scanned this drawing - this is the drawing (I also added part of my code):
This is the code I'm using in my button:
(remember it's in a deferent ViewController).
- (void)buttonPressed:(UIButton *)sender
{
Photo_ScreenGlobalView *photo = [[Photo_ScreenGlobalView alloc] init];
[self.navigationController pushViewController:photo animated:YES];
}
Usually I solve these situations with delegation. If there is a view controller which is subordinate to another (i.e. a "sub" view controller) but should have the ability to trigger navigation changes, etc... then it should have a weak pointer back to it's 'parent'. Then the parent VC should implement an appropriately named protocol with a callback for the child to use. The names of these things can be generic, such as #property navigationDelegate and requestNavigationToViewController: or they can be more semantic, such as #property userFormDelegate and userFormDoneButtonPressed:
Generally speaking, a subordinate view controller should not be able to directly modify navigation at it's parent's level; but it can trigger it via more loosely-coupoled interfaces like these.
i came back to let you all know how i actually did it.
after googling a lot found this nice and quick guide how to make DELEGATE
and working with delegate solved all my problems. if you need any help don't hesitate to send me PM.
this is the guide:
http://css.dzone.com/articles/do-not-publishcreating-your

Create a sort of navigation logic within an application: how to?

I have a number of view controllers that I want to navigate; however, I need to implement an intuitive way to move to previous ones. For the button press methods in my view controller custom classes to move forward, I do something like this:
NextViewController *next = [self.storyboard instantiateViewControllerWithId:#"NextViewController"];
[self presentModalViewController:next animated;YES];
With this in mind, how can I return back to previous views?
Why not just use the built in UINavigationController? You can hide the navigation bar and use custom controls to push and pop controllers as you wish
When using modals you simply add a button that links to the action:
-(void)goBack:(id)sender {
[self dismissModalViewControllerAnimated:YES];
}

Access a Navigation controller's main view programmatically

I've got a Tab Controller with a navigation controller which has a view, as seen in the image below:
I need to retrieve the Switches Controller from within my AppDelegate so I can do some things with it at runtime.
I believe I can retrieve the NavigationController itself by doing this:
UINavigationController *navController = [tabBarController.viewControllers objectAtIndex:0];
Not really sure how to access my SwitchesController from there though. Any suggestions?
Why not make an ivar with an IBOutlet? It's probably the most flexible solution as you can now change the ordering of your viewController's without breaking your build.
Use one of the visibleViewController, topViewController properties of UINaviationController, or call:
[navigationController.viewControllers objectAtIndex:index];
Docs: http://developer.apple.com/library/ios/#documentation/uikit/reference/UINavigationController_Class/Reference/Reference.html
Hope it helps.

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);