How do I set a view programmatically for my tabBarController? - iphone

I have a tabBarController xib. I've set the first item's class to a view controller I made (.h and .m files, no .xib). When I try to push the tabBarController, I get a warning saying the tabBarController "view outlet was not set".
I'm not sure how to set the view outlet, since I am loading from another view. I'm expecting the default grey view with detailed edges will load from my ViewController.h file because I set the class there, but instead I'm crashing with that error.
Suggestions?

Normally, you would add view controllers to the tab bar controller in the xib. They need to have a view linked up, which you can also do in IB.
If you want to do that programmatically, you should, after loading the xib, but before showing the vc, take the elements of
NSArray *vcs = [tbCtrl viewControllers];
walk through them, and set their view property to a view. When pushed, the tab bar controller will know which view to load: namely the view of the first tab. These things are really much easier to handle in IB.

Related

Display whole ViewController within another ViewController's view

Im writing an application which the main view controller is a UIViewController. It has some icons in a grid and I want to dismiss (sliding down) this grid when one of the icons is clicked. This I've done already. The problem is: when the grid is dismisseed I want another View to come from the top of the screen. This view is in this same root view controller. But I want to display the content of other view controllers in this view. For example: I want this view to show a UINavigationController with a UITableView inside it, so the user can navigate through TableViews.
I'm doing this:
HorariosViewController *horarios = [[HorariosViewController alloc] init];
[vuashView addSubview:horarios.view];
HorariosViewController is a UINavigationViewController. It shows me only a blue NavigationBar and changes like self.navigationItem.title = #"Title" won't work.
Thanks!
You can show another view controller's views as subviews but their outlets and actions remain linked to their original view controller unless you write code to make new connections, so self.whatever shouldn't be expected to affect the other view controller's properties.
(Also, if HorariosViewController is a UINavigationController, it shouldn't be created as a UIViewController.)
One approach is to have the navigation controller already there, with the icon grid presented modally on top of it. (you can set the view up this way without animations, so the user doesn't see the navigation controller underneath).
Then, when it's time for the grid to go away, it can call dismissModalViewController on itself with animation.

iPhone : Problem regarding Hidden TabBar Controller?

I want to hide tabbarcontroller on one view.
But doing so it is displaying white space and not allowing to put any image or anything else on that place.
So what should I do ?
Put one imageView with your desired image on the view controller where you do not want to show tabBar and hide tabBarController before pushing that view on navigation stack using code like
[viewControllerInstanceWhichIsGoingToPushed hidesBottomBarWhenPushed];
The method is something like this. Then Tab Bar will hide and your imageView with image will be displayed in place of TabBar.
If you add a subview to a hidden view, the subview will also go hidden.
In your case, you can have another view controller with just the activity indicator and display the view controller while the loading operation is done. And, after the loading is over, remove that view controller and show the tab bar controller. An example,
// while loading the content
appDelegate.window.rootViewController = loadingViewController;
// once the loading is over
appDelegate.window.rootViewController = tabbarController;
I have encountered this problem before as well and was not able to get anything to get into the blank space using the normal hierarchy. I got around this problem by adding another level of navigation.
ex:
right now you have at UITabBarController which contains your UIViewControllers.
Instead:
Have another UIViewController as the root and then add the tabbarcontroller onto it either as a modalviewcontroller or as a pushed viewcontroller (if you make your root a navigationcontroller). Then, your rootviewcontroller can freely put views under or over the tabbarcontroller's view, independent of whether the bar is present or not.

UIWebView error on Tab Bar Controller

I really need help on creating a UIWebView on a Tab Bar Controller. But I Bumped into a road block.
Basically I started out with the Tab Bar Application Template, then;
Removed the First and Second Controller XIB files on the resource folder (since it's not really needed
In Interface Builder, I removed default contents in the First and Second View Controller and added a View first, then a Web View after that on both the View Controller
After that, I started coding on both on the First and Second View Controller headers with just this code:
#interface FirstViewController : UIViewController { IBOutlet UIWebView *twitter; }
(also for the Second View Controller's header)
Then I linked the Outlets to the UIWebView and linked both Tab Bar Item to their Class View Controller (First Tab Bar Item linked to the FirstViewController class, then for the second one as well)
Later in both the View Controller's .m files, I added
- (void)awakeFromNib
{
[twitter loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"twitter.com"]]];
}
(and for the other one)
Now when I compiled the application, it gave me:
'First View Controller (First)' has both its 'View' and 'NIB Name' properties set. This configuration is not supported.
I looked through every youtube video about this topic, but none of their comments even mentioned anything about this kind of error, I hope someone can explain how to get through this error, thanks
In Interface Builder you can either define a view in your MainWindow.xib directly inside the TabBarController, or you can tell Interface Builder that those views are loaded from separate XIB files.
It sounds to me like you are defining the views directly inside your main XIB, so in that case you need to select the view controllers that are in the TabBarController, hit Apple-1 to open the attributes pane for the controller, and clear the "NIB name" field which is probably still set to "FirstViewController". Do the same for any other view controllers you have in your TabBarController.

How do I add a Navigation Bar to a UITableViewController in Interface Builder?

Interface builder does not let me click and drag a Navigation Bar onto a Table View Controller!!! It is super frustrating.
All I want is a table view with an edit button (done in interface-builder). If this is not possible, then how do I add a navbar progammatically?
From the outline view, make sure your Table View Controller is selected.
Then go to the Editor menu, and click on the Embed In submenu, and choose Navigation Controller and voila. You have your navigation controller pointing to your tableview controller with a relationship built in.
For a table view with an edit button at the top, use a UINavigationController, with a UITableView as the rootView. That means you're going to make a custom UITableView subclass for your table view, and use that as the rootView of your UINavigationController instance. (Programatically, it's set with UINavigationController's -(id)initWithRootViewController. It's also settable through IB.)
Then, in your UITableView subclass, uncomment the following line:
- (void)viewDidLoad {
[super viewDidLoad];
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
and voilĂ , your UINavigationController's view shows up as a table view with an edit button on the right side of the navigation bar.
Since the controller is at the top of the stack, there's no "back" button on the left, so you can use self.navigationItem.leftBarButtonItem for whatever UIBarButtonItem you create.
I agree that it's difficult to figure out how to do things like this in Interface Builder, but luckily it is possible to add a Navigation Bar and Bar Button Item to a Table View this way. Here's how to do it:
Drag a blank View (an instance of UIView) from the Library to the area near the top of the Table View. As you drag near the target area, Interface Builder will highlight it in blue to show you where to drop the View. Let go, and the View will be added as a subview of the Table View's header view.
Drag a Navigation Bar from the Library and drop it on the blank View you just added.
Drag a Bar Button Item from the Library and drop it onto the Navigation Bar.
EDIT
The problem with the above approach is that, as Bogatyr points out, the Navigation Bar will then scroll along with the Table View. Apple recommends using a custom subclass of UIViewController that owns both the Navigation Bar and an instance of UITableView resized to fit. Unfortunately, that means you would have to implement the UITableViewController behavior needed by your UIViewController subclass yourself.
Another approach that seems to work well is to create a custom subclass of UIViewController that owns a blank background view containing the Navigation Bar as well as a blank content view (an instance of UIView) that fits under the Navigation Bar. Your custom subclass would have an outlet pointing to an instance of UITableViewController in the same nib file.
This has the advantage of allowing all the view components to be created and configured in Interface Builder, and doesn't require implementing UITableViewController methods from scratch. The only detail you'd need to take care of in the Table View Controller's parent would be to add Table View as a subview of the parent's content view in viewDidLoad.
The parent could implement the action methods for the Navigation Bar's button items, and implement the delegate pattern if necessary.
From iOS6 onwards, you can use container view. So what you have to do is take View controller, add the navigation bar to it, then add a Container View to same view controller. It will automatically, add the new view controller link to your container view. Now simply delete that, and your table view controller in the story board. Now embed the table view controller to container view by control drag. Hope it helps.
First add a navigation controller and put the table view controller (as root view controller) onto the navigation controller. This is how it is done in Code because I don't use IB.
Why in the world you can't drag a navigationItem into a .xib file with File's Owner set to a subclass of UIViewController and hook the navigationItem up to the UIViewController's navigationItem outlet is beyond me. It seems like a real hole in IB / XCode integration. Because you can certainly drag an instance of ViewController to a xib file, and drag a navigationItem into the ViewController, and then set the title and barbuttonitems that way.
So if you want to define your UITableViewController subclass object's navigation bar in IB, you have to create your TableVC object in a xib file (not the one .xib file that contains the tableview for your UITableViewController, though!). You then either hook the TableVC object up to be an outlet of another object (like your application delegate), which works if you need just one instance of your TVC throughout the lifetime of your app, or if you want to dynamically create instances of your TableVC in code you load this extra .xib file manually via loadNibNamed:owner:options method of the NSBundle class.
These steps worked for me in iOS 9:
Add a View Controller to the Storyboard. Make UITableViewController as base Class.
Add a Navigation Bar object onto view controller at the top.
Add a Table View below Navigation bar.
Add a Table View Cell into Table View.
Add constraints.
This is the other easy way ;
Choose your TableViewController screen on storyboard.
Click Size Inspector symbol on the right menu and find Simulated Size
Change Fixed to Free Form
You can add navigation bar easily.

Could someone post instructions for how to create a modallly presented tab bar controller?

I'm just trying to make the most basic tab bar controller that gets presented modally. I want to use nibs, as opposed to doing it all programatically, but I really don't understand Interface Builder:
Why can't I drag a tab bar controller into my veiw?
Why does IB create another "window" when I drag a TBC to the document window?
Why are there 2 view thingys in the same nib?
Why do I get this message (crash) when I try to present the modal view: "nib but the view outlet was not set" ?
How do you remember which little connections you need to make in IB, other than the obvious ones you reference in the code?
Is there an IB tutorial out there that goes beyond just the most basic pre-made application templates and actually explains what's going on?
Why can't I drag a tab bar controller into my view?
Because only other views can be dragged onto views. A view controller is not a view.
Why does IB create another "window" when I drag a TBC to the document window?
Because every view controller has its own main view. If you double click a view controller in IB, its view opens.
If you really want to create all controllers from a NIB file, do it like this:
Create a fresh empty XIB file called "TabBarController.xib". It contains nothing but the entries for File's Owner and First Responder.
Drag a UITabBarController into this XIB. Ignore the view that gets opened (you can close it).
Configure the tab bar controller according to your needs, especially by dragging as many UIViewController objects (or UIViewController subclasses) onto the tab bar controller as you have tabs. If these child view controllers should be instances of your custom view controller subclasses, make sure to set their classes accordingly in the Inspector.
For each child controller of the tab bar, create another XIB file in Xcode, this time using the View XIB preset. Let's call these "ChildController1.xib", ... Open all of them in IB and set their File's Owner class to the class of the corresponding child controller (i.e., UIViewController or a subclass). Then connect the views in these XIB to the view outlet of File's Owner. Configure these views as you need them (by adding the actual UI elements of the child views and possibly connecting other outlets if necessary).
Close the child XIBs and return to TabBarController.xib. For each child controller, open the Attributes Inspector and set its NIB Name attribute to "ChildController1", "ChildController2", ... Then close the XIB.
In your code:
NSArray *nibFile = [[NSBundle mainBundle] loadNibNamed:#"TabBarController" owner:self options:nil];
UITabBarController *tabBarController = [nibFile objectAtIndex:0];
[self presentModalViewController:tabBarController animated:YES];
I broke down and just configured the TabBarController without using Interface Builder. The more I'm getting into iPhone development, the more I'm realizing that IB is bad, and to not use it except for the rare components with absolute layouts. In this case, all you would gain by using it would be the icons and titles on each tab. IB doesn't really provide any earth-shattering visualization on that.
I really wish nibs rendered down into some readable text format, so you could always drop to the code to understand what was going on, but that's not the case, so I'll gladly add 6 lines of code to make my program not crash