Move navigation controller and add a label - ios

I want to move the navigation controller and add an small title between the default iphone bar and the navigation controller bar. Something like that:
https://www.dropbox.com/s/6an4ywp5h1dnxy2/iphone.png
I have not idea how to do it. I'm trying to move the navigation controller with this code
self.navigationController.view.frame = CGRectMake(0.0, 54.0, 220.0, 556.0);
self.navigationController.navigationBar.frame = CGRectMake(0.0, 0.0, 210.0, 64.0);
but then i can't add the label.
Thanx

Acturely , navigationcontroller can not finish you job , you can use uiviewcontroller and uitoolbar,uinavigationbar to do that , hope it can help you .
and this is tutorial
navigationbar tutorial

My understanding is that you cannot move the default navigation bar of your navigationController. That said, you could hide your navigationController's navBar, and then add a custom navBar (via xib or code) to your view (and set it however many pixels below the top you desire) and add a label above that. Then just have the actions for button presses call the navigationController's button calls (or do it yourself).
That having been said, this whole UI would be an abnormal appearance and would probably feel weird...Not sure that I'd recommend it.
To hide the navigationController's bar:
[[self navigationController] setNavigationBarHidden:YES animated:NO];

Related

Popping UIViewController causes previous UIViewControllers View to change position

I have a UINavigationController with a UIViewController set as it's rootController, it contains a background on its UIView using an image set just under the navBar. I then push onto the navigation controller a new UIViewController and when the back button is pushed, the previous controller looks different. Using the visual debugger I can see that the self.view has moved entirely down below the navBar where previously it was at the top. I have no idea and been racking my brains as to why this might be happening
-(void)pushIPhoneMessagingContactsController:(MessageContactsViewController *)contactsController{
self.selectorView.hidden = YES;
[self.navigationController pushViewController:contactsController animated:YES];
}
On the RootViewController (iPhoneMessagingNotificationsController)
-(void)viewWillAppear:(BOOL)animated{
self.selectorView.hidden = NO;
[[[self navigationItem] leftBarButtonItem] setTintColor:[UIColor blackColor]];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];
if ([_displayType intValue] == MESSAGES_SHOWING) {
[self.notificationsViewController.view removeFromSuperview];
[self.contentView addSubview:_messagesViewController.view];
} else {
[self.messagesViewController.view removeFromSuperview];
[self.contentView addSubview:_notificationsViewController.view];
}
}
It seems the offending line was in the viewWillAppear method of the pushed UIViewController
self.navigationController.navigationBar.translucent = YES;
Somewhere else this navigationBar gets set as translucent:
[self.navigationController.navigationBar setBackgroundImage:[UIImage new]
forBarMetrics:UIBarMetricsDefault];
self.navigationController.navigationBar.shadowImage = [UIImage new];
self.navigationController.navigationBar.translucent = YES;
and to make it solid colour again:
self.navigationController.navigationBar.shadowImage = nil;
self.navigationController.navigationBar.translucent = NO;
but this code seems to mess with the layout so perhaps there is another way to change the opacity of the navBar and statusBar without affecting the layout?
What you're currently trying to do is hide or show a selectorView which really only should appear for one specific view controller.
Here's an encapsulated way to solve this that makes your selectorView a part of the root view controller, removing the connection from other view controllers. They no longer have to know about it or hide it.
Add your selectorView to your rootViewController's navigation bar titleView. (You can do this in code, or drop it in Storyboard and add an IBOutlet for it.)
self.navigationItem.titleView = selectorView;
Now when you push another view controller, its title will replace your rootViewController's selectorView title (view). Your other view controllers don't need to know anything about that view.
This is a good design approach in general. Anytime you have a control that should only appear on one view controller's navigation bar, you want to make it a part of that view controller's navigationItem (titleView, or left/right bar button items.) iOS will display the control when it presents that view controller, and hide the control when that view controller is no longer the top view controller in the navigation controller stack.
As for the 64-pixel height issue, it's likely related to some complexity in the rootViewController hierarchy that shouldn't be there.
In iOS 7/8, a view's content, by default, appears under a translucent navigation bar. Apple freely managed this for you, by insetting the first view of the view hierarchy.
From your code, it appears that you're trying to "hide" or "show" the (un)selected viewController's view.
Each view controller should have a view it controls. A view controller shouldn't be trying to control other view controller's views, or adding other view controller's views to its own view hierarchy.
Here's Apple's recommended way to approach this. Use a containerView in your rootViewController. The whole purpose of a container view is to encapsulate a view controller within a view. As your selectorView changes which view to show, you have your container view transition from one view controller to the other. (If you're not familiar with how to do that, check out this answer.)
Pin the containerView to the rootViewController's view, so Auto Layout can size it for you.
Your view hierarchy now looks like view -> containerView, instead of view -> hidden view of unselected view controller, shown view of selected view controller. Apple can adjust the first view's inset, and nothing gets incorrectly offset (by the height of the navigation control).
Update:
This question talks about scrollViewInsets and how they can be set on a view-controller-by-view-controller basis. If you do have a view controller, and you don't want its content to appear under a bar, uncheck that box.
But the best way to handle this is to "standardize" your UI, so it isn't varying from view to view. Either make the bar always be translucent, or not always be translucent. This makes transitions less "jarring" for the users.

Create a submenu iOS

I want to create a submenu that will appear right next to the first menu and that will contain more options. The first menu is hidden and only appears when a button its clicked on the navigation bar, i used the SWRevealViewController from github for the first menu, but i can't make the second one appear . Can somone help ?
Thanks for any help in advance
Basically you add another SWRevealController as front view controller of the root SWRevealController.
UIViewController *secondRearVC = // your second level menu controller
UIViewController *secondVC = // your second level front view controller
SWRevealViewController *childRevealController =
[[SWRevealViewController alloc] initWithRearViewController:secondRearVC frontViewController:secondVC];
[rootRevealController setFrontViewController:childRevealController animated:YES];
You can find example of what I've suggested here.
Other option is using other side menu controller, JASidePanels, if I'm not wrong it does what you want. Anyway you'll end up using some UIViewController containers recursively, so it's just a matter of choice.
For this effect i have created a separate view say reveal view with UITableView init, at first i am giving zero width and full height for that view. If the navigation button is pressed , i am moving the main view to right like about 100px and change the width of the reveal view to 100px, place that code in animation block.
[UIView animateWithDuration:0.5 animations:^{
//Move frame or transform view
revealView.frame = CGRectMake(0,0,1,screenHeight);
mainView.frame = CGRectMake(0, 0, 320, screenHeight);
}];

add navigation bar to UITableViewController without using NavigationController

I am trying to add Navigation Bar to a UITableViewController without using NavigationController.
So in viewDidLoadMethod of MyUITableViewController, I create a Navigation Bar using CGRect.
UINavigationBar * navBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 30, 320, 50)];
Then I present MyUITableViewController from MainViewController
[self presentViewController:controller animated:YES completion:Nil];
At this point my MyUITableViewController is overlapping with NavBar
I was thinking of creating tableViewController with initWithFram(x, y, width, height) to compensate for NavBar.
But I was not sure what height I should use and how to come up with a value. Would it have the correct scroll behavior??
What is the right way? Please note at this point I do not want to use Navigation Controller.
Is it possible w/o Navigation Controller.
Try not to use UITableViewController, but use simply UIViewController, add a UITableView object on it, and also implement the 2 protocols for table views.
You can resize the table view as you need, you can set its origin Y coordinate to 44 or 64 if you also need the status bar visible.
You can add a UINavigationBar object on top of it.
I hope doing this will help you solve the problem.

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;

UINavigationController has extra status bar gap at top

This looked simple enough when I set it up, but I can't explain why this gap is present between the status bar and the navigation bar. Also, the contained view looks like it may be properly aligned, and it's just the nav bar that is shifted down. The gap looks like the size of the status bar, so I expect that has something to do with it, but I don't know what.
Here is the code for setting up the navigation controller:
- (void)viewDidLoad
{
[super viewDidLoad];
advancedVC = [[AdvancedSearchFormVC alloc] initWithNibName:#"AdvancedSearchForm" bundle:nil];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:advancedVC];
nav.navigationBar.tintColor = [UIColor defaultNavBarTint];
nav.navigationBar.topItem.title = NSLocalizedString(#"SearchTitle", nil);
UIBarButtonItem *searchButton = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(#"SearchButton", nil) style:UIBarButtonItemStylePlain target:self action:#selector(refreshPropertyList:)];
nav.navigationBar.topItem.rightBarButtonItem = searchButton;
self.view = nav.view;
}
The rootViewController uses a view from a xib file, where I have simulated the status bar, the navigation bar, and the tab bar.
The problem is indeed that the navigation controller always expects to leave room for the status bar, which is the 20 pixel gap. I searched around for a while before I found this solution which works:
//nav is assumed to be a subclass or instance of UINavigationController
nav.view.frame = CGRectOffset(nav.view.frame, 0.0, -20.0);
//you can then add the navigation's view as a subview to something else
I originally found an answer which did this offset to the navigationbar's view, but it didn't work. It works when you do it to the navigation controllers actual view.
I use this technique to add a navigation controller from another nib to an empty view of my main nib, so I can position it anywhere within the main screen as a subview. By using an empty view as a placeholder and positioning frame on my main nib, I create a separate nib and class to manage the navigation, which manages other nibs used to handle their screens. This way I can solve the classic "how do I add a banner, image, or custom views above my navigation controller" while having a navigation controller as a subview...in iOS 5 to be specific.
It's also worth mentioning that I use the app delegate to store and access all the other controllers, so they are retained by a persistant instance which I can access from any class. Create and synthesise some properties in the app delegate of all your controllers, and in viewDidLoad create instances. That way I can reference all the controllers used in my app later anywhere by adding:
//this shows how to store your navigation controllers in the app delegate
//assumes you've added 2 properties (UINavigationController*)"navController" and (UIViewController*)"rootController" in your app delegate
//...don't forget to add #import "AppDelegate.h" to the top of the file
AppDelegate *app = (AppDelegate*)[[UIApplication sharedApplication] delegate];
[app.navController pushViewController: app.rootController animated:YES];
//now apply the offset trick to remove the status gap
app.navController.view.frame = CGRectOffset(app.navController.view.frame, 0.0, -20.0);
I had the same problem before. The code I used to add UINavigationBar to UIViewController:
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:self];
[self.view addSubview:nc.view];
Solution:
Check the box "Wants Full Screen" with Attributes inspector of your UIViewController.
You can try to set the attribute Under Top Bars unchecked from Attributes section of UIViewController.
As we all know by now, the 20 pixel shift is to provide space for the Status bar on the top.
But infact, the view controllers coordinate system is kept in place and only the navigation bar frame is shifted down by 20 pixels. This makes the navigation bar to actually overlap the top 20 pixels of the view.
Logging the navigation bars frame origin, it will show (0.0, 20.0)
So the solution is to simply reposition the navigation bar's origin to (0.0, 0.0) in ViewWillAppear.
self.navigationController.navigationBar.frame = CGRectMake(0.0, 0.0, self.navigationController.navigationBar.frame.size.width, self.navigationController.navigationBar.frame.size.height);
Since you're adding advancedVC as a subview of self.view, it is being added inside the frame of self.view which I'm guessing is already compensating for the status bar.
You can probably easily fix this by adding this line:
nav.view.frame = self.view.frame;
Just above this line:
self.view = nav.view;
-
Other Thoughts
I'm not privy to your entire setup, but self.view may not be needed at all. Simply make your advancedVC instance the rootViewController of the UIWindow instance contained in your App Delegate.
The problem was resolved by fixing the way the navigation controller was inserted. Instead of inserting it into a view that had been put onto the tabbar controller, the navigaiton controller should have been put directly onto the navigation controller.
advancedSearchFormVC = [[AdvancedSearchFormVC alloc] initWithNibName:#"AdvancedSearchForm" bundle:nil];
UINavigationController *searchNavController = [[UINavigationController alloc] initWithRootViewController:advancedSearchFormVC];
This is just one controller that is on the tabbar controller, replacing the advancedSearchFormVC at the same time. Then this nav controller was added to the array of controllers that got put onto the tabbar controller.
Sorry for any trouble, but this was one of those problems I can look directly at and not see it. I should have seen this earlier, because I had another nav controller already on the tabbar controller, and it was set up the same way.
Thanks for your assistance.
The problem is that UINavigationController.view should be added to the top view.
Just find the top one and it will be working great.

Resources