How do I add UITabBarController subview to UINavigationController - objective-c

I am new to Objective-C and Cocoa and I am trying my way through some tutorials with some success. One task is troubling me. I am trying to create a root view controller that is a navigation controller as given by this tutorial:
http://fuelyourcoding.com/iphone-view-switching-tutorial/
On the second page that is pushed I would like the option to load a subview that is a TabBarController. Is this within iOS view guidelines. Is this possible? If so, could someone give some code snippets and explain necessary instantiations and connections in IB? Your help is appreciated in advance!

No, you should not push a UITabBarController to a UINavigationController stack.
Perhaps tell us what you're trying to accomplish and someone can suggest an alternative.
From Apple's View Controller Programming Guide - Tab Bar Controllers:
Note: Although a navigation controller
can be embedded inside a tab, the
reverse is not true. Presenting a tab
bar interface from within a navigation
interface is potentially confusing for
users. A navigation interface uses one
or more custom view controllers to
present an interface focused on one
goal, which is usually the management
of a specific type of data. By
contrast, the tabs of a tab bar
interface can reflect completely
different purposes in an application
and need not be related in any way. In
addition, pushing a tab bar controller
on a navigation stack would cause the
tabs to be displayed for that screen
only and not for any others.

I cannot answer your question directly, but in my app I have a UITabBarController which displays multiple UINavigationControllers and other types of controllers. So I think you may have it the wrong way around. In other words, create a project which uses a UITabbarController as the base controller and when you select a tab, load up the corresponding UINavigationController (or other type of controller) as necessary.

Related

UISplitViewController - Multiple Detail View Controllers via storyboard segues

I'm trying to do a project for the iPad in which I'd like to utilized the split view controller. I'll be having different detail view controllers for each of the cells in the master view controller.
I saw one solution how to do this via storyboard segues in this site.
He basically linked each of his UITableViewCell to different detail view controllers. But I'd like to know if this is a "stable" or a "good" way of doing this. I mean, is it any better or as stable as doing it programmatically? What would be the consequences of doing his method, if there are any?
Here is the link to the solution I found
This is kind of a tricky one, even though it's an incredibly common use case.
1) One idea is to have an empty root view controller as your detail and it handles managing segues under the hood to quickly segue to the detail view you actually care about, utilizing the "replace" segue. This should "technically" fix having the "back" button at the top left and still allow you to pop to root and not have it show the empty controller. Haven't tested these though, so I'm not sure.
Edit: In Xcode 6, the "replace" segue is conveniently handled by a "show detail" segue which is used specifically for this type of view handling on Split View Controllers. I recommend using this method exclusively in new projects. See sample code.
2) The other idea is to have separate navigation controllers in your storyboard (one connected, the rest all stranded). One for each detail view type and tapping on the master menu will simply swap the navigation controller for the detail view to the one you care about.
Code similar to this in AppDelegate:
self.detailNavigationController = [self.masterNavigationController.storyboard instantiateViewControllerWithIdentifier:#"MyChosenNavigationControllerStoryboardId"];
self.splitViewController.viewControllers = #[self.splitViewController.viewControllers[0], self.detailNavigationController];
self.splitViewController.delegate = (id)self.detailNavigationController.topViewController;
The downside to this second way is that in memory tests, it doesn't appear that swapping a new nav controllers in frees up all of the memory that the old nav controller was using. So it's good to use for simple apps but not for anything crazy complex.

UINavBarController connecting the same UIViewController to multiple navigation controllers

I have a storyboarded app with a chain of tableviews followed by a detail view. Kind of the classic iPhone app. There are 4 tabs and each one leads to a navigation controller.
The issue is I really want to avoid unnecessary glue code since the app is basically finished. If it was possible to connect the Search and Favorites (bottom two off the tab bar) controller as 'Root View Controllers' to the same UIViewController I would be done. However, this won't work since a view controller can only be the root view controller to one tab. So as you can see I've instituted two dummy UIViewControllers that forward you to the UIViewController in the middle. Now, unfortunately, I have to write code to make that central view controller a fake root view controller to disable the appearance of the back button, and prevent popping to the blank root when you double-tap the tab bar.
Has anyone got a more elegant solution?
This appears to be a flaw in Storyboards. One workaround would be to use simple view controllers for each navigation controller's rootViewController. Put a UIContainerView in each that points to the UIViewController you want to share.

Storyboard with NavigationController and TabController

It seems like this should be easy to figure out, but I haven't had any luck this afternoon. I threw together this quick, simplified storyboard mockup of my problem.
Basically, I would like the table view controllers below to also be in a tab bar controller (in addition to the already present navigation controller). The tabs would switch between the two table view controllers.
Right now, the view controller with the buttons acts as a sort of menu. Each button leads to one of the table view controllers. Ideally this view controller would not have the tab bar visible, and would only be reachable from back buttons on the nav bars of the table view controllers.
I've tried a few different ways of embedding into a tabbarcontrollers but none of them produce the desired result:
-I've tried selecting both table view controllers and embedding those in a tab view controller. The tabbar doesnt show up in simulator, and the 'unreachable scene' warning appears.
-I've tried embedding the initial nav controller into a tabbarcontroller. This creates a tab entry for the first 'menu' page. It also causes issues with push segues once I connect the tableviews to the tabview.
I would be fine implementing some programmatic options on top of the storyboard, I just chose storyboarding for this project since it's a relatively simple presentation of data.
What is the proper way of going about this? Thanks!
A tab bar controller needs to be the root view controller of your view hierarchy. It goes against the HIG and Apple's standards to put a tab bar controller inside of any other type of container controller.
From the Apple docs:
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.
So, the bottom line here is you need to rethink your design. One option would be to set the UITabBarController as the root view of your window, and then have each of your UITableViewControllers inside of a UINavigationController, which is placed inside of the UITabBarController. In this way, you still get the navigation bar, and stay within Apple's design guidelines (you also won't get those pesky warnings, and Apple may even be throwing an exception nowadays if you try to install a UITabBarController as anything other than the root view of the window).
I accept JMStone answer but we might get into situation where we need to put tab bar controller inside other controller especially table view controller.
Please refer Storyboard navigation controller and tab bar controller
and also the good example by Matthjin: http://cl.ly/VQLa
Hopes it help some one who want to put tab bar controller inside table view controller and wants proper navigation.

Putting an ADBannerView on top of a UINavigationController

I'm trying to put an iAd banner in an app that is based on a UINavigationController (it's not the standard nav-base app proposed by xcode, cause I don't need the table view).
I'd like to place an ADBanner on its bottom, to be always visible, no matter how the user pops and pushes views.
I studied the iAdSuite example in the apple sample code, but, though it's reported among the "best practices", I don't think it's the best practice for what I need. It basically declares an ADBannerView in the app delegate class and then implements the ADBannerViewDelegate methods for every single view the app needs. That means implementing the ADBannerViewDelegate methods over and over again on every view controller class you need! It doesn't seem too smart... :(
I'd rather prefer to have an approach more similar to what Apple itself does in the tab bar based app, where you have a part of the window always occupied by the tab controller and all the views switching above without affecting the tab bar view below.
You can't directly put an ADBannerView along with the nav controller in the app delegate, because ADBanner needs to be placed in a view controller (you get a runtime error otherwise).
I tried to subclass from UIViewController, implementing the ADBannerViewDelegate in this class, and place it in the rootViewController along with a UINavigationController but I'm not having good luck with this approach...
Has anybody found a good, simple way to to this? Any hint?
Thank you for any help...
You can have just one class for ADBannerViewDelegate, and just one instance of ADBanner itself. When the currently active view changes, remove ADBanner from the old view, add it as a subview to the new view.
EDIT:
to clarify, you don't need each view implement the ADBannerViewDelegate. You only should have one class implement it (that class doesn't have to be a view controller for that matter).
You would also need to maintain a somewhere a property that would point to the currently active view (e.g. you can update that property in your Navigation Controller's navigationController:didShowViewController:animated:, or come up with your own protocol for that if your views appear in a more complex way).
Then in your ADBannerViewDelegate you'd just resize the view currently pointed to by that current view property. The actual view doesn't even have to know it has an ad in it ;)

pushViewController and Navigation Applications?

Why do Navigation Applications use pushViewController instead of presentModalViewController like all the other apps? How can a Navigation Application be modified to use presentModalViewController instead? Would it be sub-optimal to do so? Why?
Navigation view controllers and modal view controllers are there for different purposes. The first is used for display hierarchical nested contents. While you request more detailed info about an item, you go deeper in the hierarch pushing more detailed views over the stack.
The modal view is there for displaing only one view over the current. Its usefull for stuff like an info button for your app.
Your question is a little bit like asking why UISplitViewControllers use two controllers and lay their views out side-by-side. That is, UINavigationControllers use pushViewController: to manage their stack of UIViewController instances because that's how Apple decided UINavigationControllers should work. When animated into view, pushed views will slide in from the right and old views slide in from the left when a view is popped.
ANY instance of a UIViewController can use presentModalViewController to display the view of another UIViewController over top of it's own view in a manner which prevents the user from interacting with the view underneath. Depending on the device (iPhone, iPad) you have various options for the visual appearance of the newly presented view and the animation used to bring it into view.
There's nothing stopping you from writing an application that just keeps having one view bring up the next view using presentModalViewController but there'd be no reason to use a UINavigationController to do so. I've never checked if there was a meaningful difference in memory consumption or any other thing you could measure to judge whether doing so is "sub-optimal" from a technical perspective, but it's certainly not the norm so might be sub-optimal from the user experience perspective. Whether that is true or not for your app depends on whether users seem to think the interaction makes sense to them.
Navigation view controllers uses the concept of Stack.Your navigation is stored in stack that's why you can push & pop the View which shows that you can use them for the detail view ....making a hierarchy of views
whereas modal view controllers shows only one view at a time......this is generally used for new flow in app.