I have read that subclassing a UITabBarController is a non-recommended practice. However, how then is possible to implement lazy loading of the views of tab bar items?
I'm playing around with a standard app view hierarchy: In my main app delegate file (application:didFinishLaunchingWithOptions:) , I'm instantiating a custom subclass of UITabBarController with a 4 tab bar items / icons. I only need to load the first view of the first tab bar item - other views should be loaded lazily upon request. So, in application:didFinishLaunchingWithOptions:, I'm loading welcome view and pushing it into the first UINavigationController(1). The other tab bar items are empty UINavigationControllers - (2, 3, 4). Here is my custom subclass of UITabBarController that is also a delete of himself:
#interface MainUITabBarController : UITabBarController <UITabBarControllerDelegate> {
}
#end
#implementation MainUITabBarController
-(void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item{
UIImageView *image = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"TableViewBG.jpg"]] autorelease];
UIViewController *vc = [self.viewControllers objectAtIndex:item.tag];
vc.view = image;
}
#end
Currently, the view of the second tab bar item is just a UIViewController but I it will become a UINavigationController soon :)
So, back to the problem, what other (more apple-complaint) options would be to implement tab bar item action handling for lazy-loading?
If I understand your question correctly, by default TabbarController loads item's view in lazy mode. That is, unless you click on a certain item on tab bar, it won't be loaded.
You can check this by putting log on each view's viewdidload and see when it is getting called.
Related
I have made a very simple Navigation based app (UIViewController). The view has a single button on the Main RootViewController.
Next, I made 2 classes: TabOneViewController, TabTwoViewController. All good. I then created a new Class TabBarViewController. I opened up the NIB file and dropped on a ``UITabBarController onto it. The two tabs it creates in it by default were assigned (respectively) to my TabOne and TabTwo view controllers.
strong text
Then in my TabBarViewController, I made an IBOutlet for a UITabBarController, synthesized it etc etc. I linked it up in Interface builder via the "files owner".
In the RootViewController, I linked the button to my "pushView" method, and in this pushView method, I have the following code:
- (IBAction) pushView {
TabBarViewController *controller = [[TabBarViewController alloc] init];
[self.navigationController pushViewController:controller animated:YES];
[controller release];
}
The end result is it DOES push a view, but I cannot see the tab bar at the bottom, let alone any of the pages I've added to the controller.
What am I doing wrong? Why can't I link it in IB?
I am not 100% sure if that's allowed.. because you already have one tabBarController as rootViewController, and you dropped one more tabBarController as first tab controller, tabs ll overlap, considering amount of real estate you have on your iPhone, it make sense to not allow a tabViewController inside another
First, you need to allocate your view controller with your nib:
TabBarViewController *controller = [[TabBarViewController alloc] initWithNibName:#"YourNibName" bundle:nil];
Secondly, in IB, click the UITabBarController and go to the identity inspector and make sure you select your custom class. That said, unless you are overriding or adding some functionality you probably don't need the custom class at all, simply use a UITabBarController directly:
UITabBarController *controller = [[UITabBarController alloc] initWithNibName:#"YourNibName" bundle:nil];
I have a UITabBarController, which is the second item in a UINavigationBarController. Within the UITabBarController are a couple of views, one of which is a UIViewController subclass called AccountViewController. Got that?
Login View Controller -> UIViewController + UITabBarController - > Account View Tab -> Button
I want to use a button - Logout - to pop back to the Login view. How would I do that?
Assuming you are creating the UITabBarController within one of the UIViewControllers which are part of the string of view controllers within the UINavigationController where you have done something similar to this:
UITabBarController *mytabs = [[UITabBarController alloc] init];
[self.view addSubview:mytabs.view];
mytabs.delegate = self; // This is key to getting back your UINavigationController
You can call this from within one of the UIViewControllers that are added to your mytabs.viewControllers array like so:
[[(UIViewController *)self.tabBarController.delegate navigationController] popViewControllerAnimated:YES];
You can also specify if you want it to go to a specific viewController index in the UINavigationController stack ( just in case your Login viewController isn't the next one down or the root view controller ).
- i have a FirstViewController and a SecondViewController, each has its xib
- in the MainWindow.xib i have a UINavigationController, which is connected to IBOutlet
- in the AppsDelegate i call
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
FirstViewController * fv = [[FirstViewController alloc] init];
[navigationController pushViewController:fv animated:NO];
[fv release];
[self.window addSubview:navigationController.view];
[self.window makeKeyAndVisible];
return YES;
}
4) the problem is, when i want to manage Navigation item through interface builder... like for the first view i want to add a button to the right and customize the back text and the title
sure i could do this using code :
(by fv.navigationItem.rightBarButtonItem = ... and fv.title=#"...") but i want to achive this in interface builder
in my FirstViewController.xib and SecondViewController.xib i add a Navigation item and add the a right Bar item
the problem is, it never shows up and the title doesnt alter
if i open MainWindow.xib and add a ViewController (FirstViewController) under the NavigationController (so its listed under it = make it the rootViewController for the NavigationController) and also add Navigation item and Bar Buttom item, whoala, the NavigationBar at the top has the left button
again this would be great... BUT i cannot do the same think for the SecondViewController, because in interface builder, there can be only one rootViewController under the Navigation Controller... and again if i add the Navigation item in SecondViewController.xib it doesnt show up:(
- so ho can i manage the Navigation items and Bar button items for multiple ViewControllers in interface builder
(i looked at most tutorial, but they do it inside the code, by .navigationItem.rightBarButtonItem, what i want to avoid)
ok, the best solution i found
is to design the buttons in Interface builder and link them via Outlet, then in code i simply add them
fv.navigationItem.rightBarButtonItem = myOutletButton;
i didnt find a way to do it just only in interface builder so it gets bind automaticly :(
If u like to do a separate NVC please instaniate it not from main view, do this from different view's separate.
I'm adding navigation to subviews in my app from the home view.
I understand the concepts of pushing and popping view in the navigation stack, however, I don't want the navigation bar in the home screen.
Basically, when the user leaves the home view to any sub view, I'd like them to see the "Home" button on the left of the button nav bar, but no nav bar in the home view.
Any help would be appreciated.
It sounds like you want to start out with a bare UIViewController, containing your home screen with your own custom buttons.
The UINavigationController should come into play only when a user performs some action. Do this by
[navVC setModalTransitionStyle:UIModalTransitionStyleCrossDissolve]; // pick an effect
[self.viewController presentModalViewController:VC animated:YES];
Where navVC is the navigation controller, and self.viewController refers to your (new) main view controller. (add a suitable line IBOutlet UIViewController *viewController; + #property line + #synthesize line)
You need to fiddle a bit in the way the app starts up, for now it will probably show the navigation controller directly. If you are using a xib, you can do this by adding a UIViewController while leaving the navigation controller there as it stands. In application: didFinishLaunchingWithOptions: you'll find a line saying
[window addSubview:...];
which actually determines which viewcontroller's view is first visible. Change this to:
[window addSubview:self.viewController.view];
If you've done all this correctly, you've inserted the extra UIViewController between startup and navigation.
I'm creating a navigation-based app which displays a graph, rendered with openGL, and a tableview listing disclosure buttons of all of the elements that are displayed on the graph, and a settings disclosure button.
The navigation controller is also a tableview delegate and datasource, and the tableview is added to the view programatically and has its' delegate and datasource set to 'self'. The OpenGL based graph view is added via IB.
The problem I'm having is that I'm trying to push a view controller (either settings or graph element properties) within the didSelectRowAtIndexPath method. The method registers and the new view is pushed on, but the tableview stays and obscures part of the view that was pushed on, as if it has a different navigation controller.
I can't seem to set the tableview's navigation controller to be the same as the rest of the UINavigationControllers' view.
Does anyone know how I could fix this?
My navigation controllers' initWithCoder method, where the tableview is added, appears as follows:
elementList = [[UITableView alloc] initWithFrame:tableFrame style:UITableViewStyleGrouped];
elementList.dataSource = self;
elementList.delegate = self;
[self.view addSubview:elementList];
Further in the source file, the DidSelectRowAtIndexPath method where the navigation controller is pushed appears as follows:
Settings* Controller = [[Settings alloc] init];
[self pushViewController:Controller animated:YES];
[Controller release];
Fixed by just adding a UITableView in IB, adding IBOutlet to elementList, and setting the UIViewController as the delegate and datasource via IB.
Stack Overflow can be really useful for putting your problems to words so the solution becomes obvious.