I've yet to find an example that does this. A client wants a navigation-based app where two sections (one nav-screen each) need to have a few views, controlled by a tab bar. I'm having difficulty setting up the logic of connecting all of the elements and making sure the flow makes sense (ex. hitting the nav-bar's back button on any of the tabbed views will lead back to the same screen).
I answered a similiar question not long ago (if I understand your question right). This will add a tabbar as a rootcontroller and each tab has its own navigationcontroller.
Right design pattern for tabbed navigation views?
EDIT
From UITabBarController documentation
Because the UITabBarController class inherits from the
UIViewController class, tab bar controllers have their own view that
is accessible through the view property. When deploying a tab bar
interface, you must install this view as the root of your window.
Unlike other view controllers, a tab bar interface should never be
installed as a child of another view controller.
As #Jolly good has mentioned, Apple HIG suggests not to do such implementations.
The only other way I can suggest is to try implementing a custom view controller that looks/behaves like a tabbarcontroller and make use of that.
Another hack I can think of, not sure if it'll work or if its possible, create a tabbarcontrller the usual way and then set the hideBottomBar property, and make the bottom bar visible only when you want it to be visible.
It is possible, despite the documentation that #Jolly good cited.
As a real world example, let me describe a game of mine. It consists of a UITabBarController (UITBC) and UINavigationController (UINC). The "main" window of the game is the Root view of the UINC, and when the game is active, it hides both the tab bar and nav bar to maximize screen real estate (not as necessary for iPad, but still...).
When the game is idle (paused, between rounds, etc.), it pushes the UITBC onto the nav bar. It also tells the UITBC to make a particular VC selected. That allows access to the additional screens (About, Scores, Instructions, Settings, etc.), and the player can navigate using the tab bar. In addition to the additional views on the tab bar is the game controller that simply pops the UITBC from the nav bar to revert to the game view to un-pause, go to next round, etc. (Obviously, the UITBC is cached within the game VC so it can be pushed back when necessary.)
Using this sort of logic, it is possible to mix and match tab bar and nav bar controllers for complex navigation. You can get away with this for games; just make sure that any non-game app follows Apple's HIG so as not to confuse the user.
I hope this helps.
Related
I am making an app that has both a bottom bar and a top bar (both are customized) and i want them to stay there the entire length of the app while the middle portion switches between views. But the kicker is at some points in the app, i want to have the top bar and bottom bar slide off the screen and be able to be dragged back on.
What i was thinking was to have one main UIViewController with three UIViews (top bar, middle section, and bottom bar) each running code from their own respective files. Sort of like how a Tab bar works with a nav controller. or do i have that backwards? i dont really know... but any constructive advice helps =)
Im fairly new to xcode and i've been trying to find a way for a few days now, so please dont be too harsh on me. Thanks!
In general, we build one view controller for each 'screenful' of content. So the basic advice for you would be to make the app in a way where each 'section' is it's own view controller. This is especially important to the MVC paradigm, where your business logic should be in the viewControllers, not the views (just display and interaction logic there). If you had just one view controller, it would get convoluted FAST by trying to manage multiple sections.
A good route may be this: Embed the whole hierarchy in a navigation controller, which gives you the top bar. Then make a custom view controller class which knows how to make your bottom bar, and have each section subclass that.
The side effect is that the bottom bar will be uniquely created for each section VC. If that is not desirable for you, you can explore view controller 'containment'. It is basically a technique for building components like the navigation controller, which keep certain elements onscreen for a long time, while exchanging 'content' view controllers for a smaller portion of the screen. It's not the easiest thing to do, and should be considered carefully. However, if you really need to keep the same instance of something on screen while other view controllers come and go, it may be the right way to go. That said, consider the other idea first (each section manages it's own bottom bar). You can accomplish it in a way that promotes code re-use, etc.
Sorry for the vague title!
I am trying to achieve the following functionality: A user is first presented with a UINavigationController containing a UITableView. When the user taps a cell in the table view, I want to push a new view which contains a UITabBarController (that'll stay visible regardless of the currently visible UIViewController) and a UITableView again, that people can again select a cell from and which will then again push to UINavigationController.
If a user selects a tab from the UITabBar, I want the first screen (without the UITabBar) to be the one that users can go back to, not the tab they just came from. Also, if a user selects one of the UITableView items on any of the tabs, I want the back button to go back to the previously displayed screen (as you'd expect with a standard UINavigationController)
I've spent hours trying to find the answer to this and I just can't anywhere! I hope I haven't been too vague or confusing in my explanation.
James.
If your desired UX is confusing to explain here, imagine how your users will feel! I would reconsider the intended design.
From the View Controller Programming Guide:
An application that uses a tab bar controller can also use navigation
controllers in one or more tabs. When combining these two types of
view controller in the same user interface, the tab bar controller
always acts as the wrapper for the navigation controllers. You never
want to push a tab bar controller onto the navigation stack of a
navigation controller. Doing so creates an unusual situation whereby
the tab bar appears only while a specific view controller is at the
top of the navigation stack. Tab bars are designed to be persistent,
and so this transient approach can be confusing to users.
That said, you can probably hack something close to what you are talking about but you'll need to write a bunch of code to handle the navigation using the UITabBarControllerDelegate and UINavigationControllerDelegate methods and keep track of whatever state you need to know where you want to navigate to based on a user action. Odds are you'll end up with something complicated to code, maintain, and worse, use.
I'm building an iPhone app and I'm sort of confused about which approach should I choose for views and controllers.
I would like to have a tabbar at the bottom with three options. I would also like to have a main view displayed when the app shows (along with the tabbar) but I don't want this view to be part of the tabbar options.
So, when the app begins, the tabbar has no option selected but the main view displayed. When a tabbar options is selected, in its top bar it should display a back button to the main view. When the back button is pressed, the main view display again with no tabbar option selected.
Which approach should I choose?
Hope it makes sense.
Thanks.
I understand what you're trying to do, but you shouldn't do that. I don't like that design at all. You should have one navigation controller for each tab.
You should probably read Apple's Human Interface Guidelines as it's possible they would reject your App if they thought such an implementation with a TabBarController was confusing.
As an alternative, you could possibly have the "main view" as you call it accessible with a button in the Navigation bar at the top and then add that to all three tabs. Not necessarily a better design but you probably wouldn't be breaking the guidelines.
A better alternative might be to use a UIToolBar at the bottom instead of the Tab bar which has the three buttons spawning your views modally which can then be dismissed as you suggest.
Remember though, your App's users have built up a knowledge of how App's are generally supposed to navigate, feel and control so you should think carefully before deciding to go against that.
Firstly, I think you should reconsider giving your Main View it's own tab. That way it's a no-brainer for the user to return to that screen. BUT, if you STILL don't like that idea, read on...
The UITabBarController has the unfortunate side effect of not being able to be removed once created (even if you delay it's creation by instantiating it programmatically).
SO...
Option 1: Make your MainView a modalPresentation sub-view, displaying it ON TOP of one of the views in your tab bar (hiding the tabs until you're ready to show them again).
Option 2: Give a subview of your first tab a...
mySubViewController.hidesBottomBarWhenPushed=YES;
This will make the UITabBarController disappear temporarily (just on that view, until you're ready to show the tabs again).
Both options seem kinda messy to me, but they are possible. Depends on how well you execute them, I suppose.
Hope this helps!
You could add the main view as another tab.
OR
You present the main view modally when the app starts over the tab bar views.
The first option would be used more if the view holds the same kind of content as the tabs, for example if the app was an online store, the tabs would be Categories, Search and Recently Added, with what you call the "main view" being the Home page (showing offers or something). (So all the views/tabs would be showing products on the store)
The second option would be more if the content of the main view is different to the tabs.
Keeping with the online store example, if the tabs were Categories, Search and Recently added and what you call the "main view" being a login/logout screen. (so the tabs would be showing products, but the modal view ("main view") being more admin related, and it's main purpose not being to display products.
hi
I'm new to objective-c
i need to create a view, that has four buttons at the bottom, and a view above them that changes according to which button you press.
now i've been reading a bit of tutorials, and i still have difficulties understanding the different nib files.
But i'm wondering.
i have 'tab bar controllers' in the controllers sections in the library and i have 'tab bar' in the 'windows views and bars' section.
now according to what i've read, and understood...
i have to use tab bar controller and add it to the 'Mainwindow.xib' and implement and link the stuff.
But can't i just add a tab bar in my 'appnameViewController.xib', and manage the tabbar items' click to change views. without relying on the tb controller??
If you want tab bar functionality you really should use UITabBarController. While it is possible to repsond to the the taps on the tap bar and switching views by yourself it is not recommended. Some reasons why:
You would just duplicate code that UITabBarController already does.
UITabBarController will handle things like unloading views not on screen when a memory warning is received.
If you end up changing the amount of tabs in your application it would still just work with a UITabBarController.
There are probably many more better reasons but since an iOS device have limited memory the memory aspect alone would make it a no brainer.
You need to familiarize yourself with the Model-View-Controller design pattern, which Cocoa follows religiously. Controllers deal with the application-specific logic the user interface (the views) provides.
For example, a button is a view but a controller handles the button's click (and setting its enabled/disabled state, etc.) depending on application logic.
I think you are confusing the tab bar view with it's view controller (UITabBarController).
Apple's documentation explains it well:
http://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/TabBarControllers/TabBarControllers.html
I am using a UITabBarController as well as a UINavigationController on my app.
In my UITabBarController I am using more than 5 items so I automatically get the 'More' item.
I've managed to add a saving procedure so the order of those items will be kept in case somebody changes the order etc.
With 'More' active I get the More navigation controller with the 'Edit' item positioned under my UINavigationController. Both navigation controller are visible. When I click on 'Edit though the More navigation controller disappears and seem to be hiding under my UINavigationController and therefore I can't see/use the 'Done' function to save my new order
What did I miss?
Cheers
It sounds like you have a UINavigationController as the main VC of your app, and a UITabBarController as one of the VC's on its stack.
I believe Apple actively discourages people from doing this in their apps, and so do I. It is never done in the iOS itself, and I have never seen it in any third-party apps either, so users will probably be confused.
I think you should embed the UINavigationController inside the UITabBarController instead of the other way around, or you could just choose to use another way of showing what you want to show.
I believe iOS does use both navigation controller and tab controller at the same time in their iPod app. The navigation controller takes you to the playing song and back and at the same time you have the tab controller when you select songs/albums/playlists etc. However, the navigation controller (or tab bar controller) seems to be custom made as it handles the More->Edit case by hiding the navigation bar underneath the Edit bar, which is not what the default UITabBarController does.
All in all, I see Apple is rather "creative" when it comes to UI design. For example, in the email app, "New" button is in the lower right corner (bottom bar) while in the SMS app the "New" button is in the upper right corner (navigation bar). I think they pretty much make custom UI to fit the individual needs of the app instead or rigidly following some consistent design.