How to use same UINavigationBar for all UIViewControllers - ios

In my app, I have to show same NavigationBar for all UIViewControllers. This NavigationBar has three buttons and these three buttons which will be act as TabBar functionality, that is each tab has its own stack cycle. I have created custom view for NavigationBar with three buttons, but after adding this custom view to HomeViewController, I have to manually add this custom view for all other view controllers. I don't want to do this.
Is there any simple method to achieve this?

There are a couple of ideas that come to mind. First of all, you could use view controller containment and actually have 1 controller that implements your custom nav bar, and then swap out the contained controller as necessary.
If that's not feasible, you can simply use inheritance and have all your custom controllers inherit from a controller that has the nav bar in place.

Another option could be to write your own UINavigationController subclass. I'm not certain if you can override the UNavigationItem behavior, but if you can, you can just just do that -- instead of the UINavigationController taking its child's UINavigationItem to update its own UINavigationBar, the UINavigationBar perhaps just stays the same, like you're expecting/hoping.

Related

TabBarController with NavigationController

I have a TabBarController with 3 tabs set up in my storyboard. I want to have each tab have its own navigation controller. However, I don't want to embed each one in a nav controller, cluttering the storyboard and then having to style the navigation each time. Is there any way to do this programatically? In other words each time a tab is tapped, the resulting view controller will be set as the root of one existing navigation controller?
I don't think that there is a way to 'set' the rootViewController every time, but you can do 3 navigationControllers in your storyBoard and build a subclass of UINavigationController. That way you don't have to set it every time. Subclassing UINavigationController has become possible since iOS 6 (See documentation):
The UINavigationController class implements a specialized view controller that manages the navigation of hierarchical content. This navigation interface makes it possible to present your data efficiently and makes it easier for the user to navigate that content. You generally use this class as-is but in iOS 6 and later you may subclass to customize the class behavior.

Best way to share nav bar across multiple views?

I have three view controllers that I want to have the same navigation bar on but I can't figure out a way to "share" the navbar between those three views. Is there a more efficient way to link up the nav controllers with the view controllers so that I don't have three different navigation controllers even though the navigation controllers are exactly the same?
In addition, I have a tab bar controller if that makes a difference.
Picture to clarify:
As Ch0k0I8 mentioned, UIAppearance is a good way to set a common UI theme throughout the app.
If you are looking for the same functionality between navigation controllers, then you should subclass UINavigationController and implement the common functionality there. Then you can use your custom navigation controller in the storyboard or in code in the 3 places you wish. To put your custom subclass in the storyboard, drag a UINavigationController onto the storyboard like you normally would, then change the class to your custom navigation controller class in the utilities tab. Here is what a custom UINavigationController subclass might look like:
class CustomNavController: UINavigationController {
override func viewDidLoad() {
super.viewDidLoad()
// do whatever custom setup stuff you want here
}
// override other methods for different customizations
}
You need to use UIAppearance.
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIAppearance_Protocol/index.html#//apple_ref/occ/intf/UIAppearance
[[UINavigationBar appearance] setTintColor: color];
You're using a storyboard, and from what you're describing, you don't need three nav controllers. Instead, connect the three UIViewControllers by ctrl-dragging from one to the next to create a push segue. Don't use the UIAppearance proxy; just set customize the bar's appearance in your navigation controller's rootViewController's viewDidLoad method.

How to change view with UITabBar (without using UITabBarController or addSubview)?

I've tried a lot to get this done.I don't want want to use addsubview or uitabbarcontroller. I want to switch the view when I tap on different tabs and tabbar should stay there. Thanks a lot in advance.I m a newbie.I want to use uitabbar not uitabbarcontroller.
A simple approach would be to wrap the view controllers you are inserting in UITabBarController in a UINavigationController then you can simply push your new view to that UINavigationController and the tab bar would be always visible!
For more details refer Apple Docs
Edit:
If you don't want to use UITabBarController then you need to do 2 things:
Add the tab bar View to UIWindow that way it would be always visible.
Scale/adjust the views in your view controllers to leave space for the tab bar

UINavigationBar inside UITableViewController

I have some static cells that I want to display, so I have a UITableViewController. There is also a NavigationBar in this scene that contains some buttons at the top. The setup looks like this:
If I had a UIViewController that contained a UITableView in it, the setup would look like:
So, the question is:
Why does the Navigation Bar have to be embedded inside the UITableView when using a UITableViewController? (I have tried putting it elsewhere but IB won't let me)
I know that UITableView is a subclass of UIView, but is it OK that the top level element in the hierarchy is not a View (but a TableView)?
Thanks.
You shouldn't be placing your UINavigationBar in your UITableView. You should be putting your UITableViewController in a UINavigationController, because that will provide a UINavigationBar for you.
So if you select your UITableViewController in the storyboard, you can choose Embed In -> Navigation Controller from the Editor menu. This would be the proper way to do it.
There are two ways to use a UINavigationBar in iOS:
Embedded inside a UINavigationController (recommended)
As a standalone object
For your particular situation, I'd recommend that you put your UITableViewController as the rootViewController of a UINavigationController. That way you automatically get a navigation bar which you can customize according to your needs. In a typical user experience, when you tap some of your table view rows a new view controller will be pushed onto the navigation stack, so you'll probably end up needing a navigation controller anyway.
What if you decide to use a navigation bar as a standalone object? This is perfectly fine, you can use it inside a view hierarchy as an ordinary UIView, but you'll need to create another object that implements the UINavigationBarDelegate protocol and set it as the delegate property of your navigation bar. If you use a UINavigationController the delegate is already set and configured for you. You also need to add/remove navigation items (instances of UINavigationItem) to your navigation bar by using the pushNavigationItem:animated: and popNavigationItemAnimated: methods.
And about your question on the view hierarchy, you can use a UITableView anywhere a UIView is required. The only caveat is that a UITableView is a view hierarchy on its own and that may restrict your layout a little bit.
The way a UITableViewController works, is its root view is a UITableView. So there is no way to put the UINavigationBar anywhere other than in the UITableView.
I tend never to use a UITableViewController as it doesn't really give you much.
If you particularly want to use the UITableViewController, I don't believe that there is any real problem in having the navigation bar within the table view. You just need to make sure that you set the contentInset on the table view such that the navigation bar doesn't block the content. Though it seems a bit backward to do it this way.
My recommendation would be to just use a normal UIViewController with a navigation bar and a table view.
If you actually need functional navigation, you need to put your UITableViewController within a UINavigationController.
Hope this helps :)
Let me know if anything is still unclear.

Adding Popover to current Navigation Controller hierarchy

I've seen a lot of other questions on here about adding a UINavigationBar to a UIPopoverController. All of the examples I've seen follow one of two patterns:
In the init or viewDidLoad method of the Popover subclass, you alloc-init a UINavigationBar directly, as suggested here. This method is a little hacky, and while it shows up nicely, if the popover is a UITableViewController, you have to mess with a bunch of things to make sure the navigation bar you just added doesn't overlap one of your cells.
Alternatively, a lot of post suggest creating a UINavigationController just before presenting the popover, as shown here.
With the second method, however, won't the popover be the only controller in the newly created navigation controller? And if my view that I'm presenting the popover from is itself already in a navigation controller, the popover will NOT be in that same navigation controller, correct? It seems to be that the more appropriate thing to do would be to add the popover being created as another controller in the navigation controller that already exists (and which the controller that presents the popover is already a part of). Is that possible? Or is there a reason why the navigation controller for the popover needs to be independent from the navigation controller for the presenting controller? Or am I totally missing something here?
You have many questions, young Skywalker. :)
Creating a UINavigationController and then embedding the controller you would like to present is the way to go.
Don't get confused by all the controllers involved here:
UIPopoverController is a construct that shows an existing UIViewController in an overlay like style. UIPopoverController itself even isn't a subclass of UIViewController. The name is misleading.
So UIPopoverController hosts another controller. In your case, we let it host a UINavigationController.
UINavigationController is a subclass of UIViewController. It is a container controller and can handle a stack of UIViewControllers.
On that stack we push one UIViewController: the one you want to display and garnish with a UINavigationBar. Since Mr. UINavigationController comes with a build in UINavigationBar, he's our friend.
There is no need to subclass UIPopoverController. You just keep one static reference to it around so you can dismiss the current open popover in case you want to present another.
It does not matter where you present the UIPopoverController from. It will always be a popover. Even if presented from an existing UINavigationController. Only if you use presentViewController: you will get different results depending on the controller you're presenting from (modal or pushed on top of the stack).
won't the popover be the only controller in the newly created navigation controller?
No, the popover will contain the navigation controller and the navigation controller will only contain its root view controller (which would otherwise have been added directly to the popover as its root).
You seem to be a little confused about the relationship between the popover and the popover root view controller...
the popover will NOT be in that same navigation controller, correct
Yes, correct. The popover is effectively a window floating above all other views
Or am I totally missing something here?
Maybe... The popover would usually be used for displaying something modal, transient and smaller than full screen size. Putting a navigation controller in the popover and adding views to it is the normal approach.
Adding a navigation bar to a popover isn't hacky. A navigation bar is just another regular view. That also means that using a UITableViewController with it, the navigation bar will overlap the table view, as the UITableViewController's view property just returns the controller's tableView property. If you want to add a navigation bar above a table view, without it overlapping the table view, use a regular UIViewController and add your navigation bar and table view the normal way. UITableViewController should only be used if your only view within that view controller is a table view.
Having said that, I do agree with others that just using a navigation controller without using its navigation features is the most common approach.

Resources