add a Navigation controller to a UIViewController - iphone

I've just worked through a tutorial on how to create a Navigation controller starting with a Window-Based application project.
Now, I'm trying to figure out how to applied the methods I used in the tutorial with a root view that has a tab bar controller.
I've set up a tab bar controller, again using the window-based app project, and added four tab bar items that are linked to their respective UIViewController classes/nib.
Can I add a nav controller like I did with my window-based tutorial to the UIViewController classes?
Here is how i created a nav controller by itself:
#import <UIKit/UIKit.h>
#interface NavAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
UINavigationController *navController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UINavigationController *navController;
#end
#import "NavAppDelegate.h"
#implementation NavAppDelegate
#synthesize window;
#synthesize navController;
#pragma mark -
#pragma mark Application lifecycle
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
[self.window addSubview:navController.view];
[window makeKeyAndVisible];
return YES;
}
etc...

Both UINavigationController and UITabBarController are controllers of controllers, i.e. they manage multiple UIViewControllers. The UIViewControllers in turn manage the views. So the title of your question does need revision.
The standard setup is this: UITabBarController is the root controller. Each tab controls either a UIViewController or a UINavigationController which in turn manages UIViewControllers.
So you add UIViewControllers or UINavigationControllers to your tab bar items.
Thus, the direct answer to your question is: no. You cannot add a UINavigationController to your UIViewControllerbut rather the other way round.

Related

NavigationController and ToolBar Issue

I have a Navigation Controller with two Views. The First View is a ViewController with a TableView and the Second View is UIView with some UILabels and a UIWebView. When selecting a cell from the TableView, the Navigation Controller pushes to the Second View.
I've added a UIToolBar to Navigation Controller and some buttons.
My problem is when the Navigation Controller pushes to the Second View (UIView), my UIToolBar appears but without the buttons.
I would like to either show different buttons or remove the UIToolBar from the Second View.
I think I need to do something within the AppDelegate, I'm just not sure what and how.
Here is how my XIBS look:
MainWindow
- App Delegate
- Window
- Navigation Controller
-- Navigation Bar
-- ToolBar
-- View Controller
--- Bar Button Item
--- Navigation Item
---- Bar Back Item
ViewController
-TableView
DetailView
-View
--Web View
--Label
--Label
Code:
AppDelgate.h
#interface AppDelegate : UIResponder <UIApplicationDelegate>
{
UIWindow *window;
UINavigationController *navigationController;
UIToolbar *toolBar;
}
#property (nonatomic, strong) IBOutlet UIWindow *window;
#property (nonatomic, strong) IBOutlet UINavigationController *navigationController;
#property (nonatomic, strong) IBOutlet UIToolbar *toolBar;
#end
AppDelegate.m
#implementation AppDelegate
#synthesize window;
#synthesize navigationController;
#synthesize toolBar;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Override point for customization after app launch
[window addSubview:[navigationController view]];
[window makeKeyAndVisible];
}
- (void)applicationWillTerminate:(UIApplication *)application {
// Save data if appropriate
}
#end
Any help would be appreciated. Thanks
You have to specify the toolBarItems for each View you load onto the stack. So,
-(void)viewDidLoad{
[self setToolbarItems:myArrayOfItems];
//do this in every view controller
//other code.
}
I cant get you clearly. i suggest this with the assumption. If you want add button in the top bar of the nextview means, you dont use toolbar for that. You can add button in the navigation bar itself.
you can add the button using addsubview method.
Initialize UIbutton using initwithframe. then add that as a subview of navigation controller.
[navigationcont addsubview:button];

Subclassed? UITabBarController wont autorotate

Noobie so bear with me.
I've have been following the O'Rielyy Learning iPhone Programming and various threads on here to build my first iPhone App. So far so good, but the final stumbling block at the projects end is getting the App to autorotate (the beta using only uiwebviews was rejected for not auto-rotating)
I have the mail App delegate, which adds a UITabBarController
// myNewsUKDelegate.h
#interface myNewsUKDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate> {
UIWindow *window;
UITabBarController *tabBarController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
#end
// myNewsUKDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Add the tab bar controller's view to the window and display.
[self.window addSubview:tabBarController.view];
[self.window makeKeyAndVisible];
return YES;
}
There is are .h and .m files for tabBarController - I added all the UINavigationControllers in IB, which in turn add a UITableView
See image at http://flatearth.co.uk/nib.png (too noob to post images in questions!)
From my reading I understand that the issue is the UITabBarController I added to the main view needs to be 'subclassed' and have this code added.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
The next view down/in/subclassed (whatever the correct terminology is), which has .h and .m files is the FirstViewController which adds the table view, this has shouldAutorotateToInterfaceOrientation already set.
#interface FirstViewController : UIViewController <UITableViewDataSource, UITableViewDelegate> {
UITableView *tableView;
NSArray *userList;
}
#property (nonatomic, retain) IBOutlet UITableView *tableView;
#property (nonatomic, retain) NSArray *userList;
#end
#implementation FirstViewController
#synthesize tableView;
- (void)viewDidLoad {
[super viewDidLoad];
// I tried adding
self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
// lots of other code ; )
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
So the problem appears to be that when [self.window addSubview:tabBarController.view]; adds the tab bar it doesn't add the shouldAutorotateToInterfaceOrientation returning YES bit.
It appears that I need to add a tabBarController subclass, with the shouldAutorotateToInterfaceOrientation in it. So I read up and tried this, as suggested on the interwebs...
// tabBarController.h
#import <UIKit/UIKit.h>
#interface tabBarController : UITabBarController {
}
#end
// tabBarController.m
#import "tabBarController.h"
#implementation tabBarController
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
#end
and adding
#import "tabBarController.h"
to myNewsUKDelegate.m
But that fails with "error: accessing unknown 'view' class method" at the
[self.window addSubview:tabBarController.view];
line in myNewsUKDelegate.m
Further searching hasn't produced anything helpful and my recent Xcode knowledge has now ran dry : ( Any help appreciated.
From my reading I understand that the issue is the UITabBarController I added to the main view needs to be 'subclassed' and have this code added.
No, you don't need to do that. The tab bar controller determines if it supports a specific interface orientation or not by asking all its child controllers if they support this orientation. In your case, these seem to be navigation controllers, which in turn ask their current child controller if it supports the orientation.
In other words, you have to make sure that all your custom view controllers return YES for the desired interface orientation.
You don't need a subclass, you need a Category on UITabBarController. Basically you create a file called UITabBarController + Autoresize.h (and .m)
In the .h:
#import <UIKit/UIKit.h>
#interface UITabBarController (Autoresize)
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation;
#end
in the .m:
#import "UITabBarController + Autoresize.h"
#implementation UITabBarController (Autoresize)
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
//do custom checks here if you only want to autorotate it in certain views or whatever
}
#end
but as the other poster pointed out, ALL the parent views of the view you wish to rotate must support rotation.

One UIViewController with many UIViews

I'm creating an app with one UIViewController and many UIViews. I have MainViewController with a UIView underneath it that displays when loaded up and a few other UIViews all in the MainWindow.xib. How do I go about switching from one View to the next?
Update:
Thanks for the reply.
I have added MainViewController to my appDelegate.
On FinishedLaunching: [window addSubview:[viewController view]];
That View Controller has a function in it called goToNextPage.
-(IBAction)goToNextPage:(id)sender{
[self.view removeFromSuperview];
[self.view addSubview:tableOfContents];
}
In Interface Builder I have that View Controller added to MainWindow.xib. Under that View Controller I have a UIView (called Cover) that loads as it's child on startup and another UIView (eventually many) named TableOfContents that is on its own.
I tried to post an image of my MainWindow.xib here but apparently my Reputation isn't high enough.
The UIView Cover has a button on it that is linked to the goToNextPage function.
When I hit the button the page goes blank as if the one view is successfully being removed but the next is not being loaded.
How do I get the goToNextPage function to switch the preloaded UIView Cover with the other UIView called TableOfContents?
Another Edit:
BookTest6AppDelegate.h:
#import <UIKit/UIKit.h>
#class MainViewController;
#interface BookTest6AppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
IBOutlet MainViewController *viewController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet MainViewController *viewController;
#end
BookTest6AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
[window addSubview:[viewController view]];
[window makeKeyAndVisible];
return YES;
}
MainViewController.h
#import <UIKit/UIKit.h>
#class TableOfContents;
#interface MainViewController : UIViewController {
IBOutlet TableOfContents *tableOfContents;
}
#property (nonatomic, retain) IBOutlet TableOfContents *tableOfContents;
-(IBAction)fGoToTableOfContentsController:(id)sender;
-(IBAction)fGoToNextPageController:(id)sender;
#end
MainViewController.m
#import "MainViewController.h"
#import "TableOfContents.h"
#implementation MainViewController
#synthesize tableOfContents;
-(IBAction)fGoToTableOfContentsController:(id)sender{
[self.view removeFromSuperview];
[self.view addSubview:self.tableOfContents];
}
-(IBAction)fGoToNextPageController:(id)sender{
}
My UIView Classes basically just initiate buttons that link to the functions defined in MainViewController.h.
First you need to know when switching from one to another.
Then you say it to your MainController and addSubView to the mainController.view an another view.
Maybe if you give us more informations or code we could help you a little more :-)
Good Luck
Vincent
Edit :
[self.view removeFromSuperview];
Here you are removing the window view. I think it's not the better way ^^ Try
[ viewController.view removeFromSuperview ]; :-)
Does it work better ?
Edit :
Edit bis : han, it's my fault. You need to remove controller and add another one in the app delegate and not in your mainController (you could do it too, but no with your actual code).
You have two options :
1°) Declare all your controllers in your app delegate.
2°) Declare all your controllers in one main controller. But the main controller would be here to "control" others one.

Using Navigation Controller in a subview of View based Applicatin

Some one please help me with this. I am developing an iPhone app and have stared with View Based Application. I have buttons on my root view screen to take user to other views with their own nibs and classes. On one of those views I need to display a table getting data from SQLite database and then display detail of the selected item depending on the selection from the table. At later stage I also need to add forms to add data.
Now, how to add a Navigation Controller in that view for drill down? Can we convert a View Controller to Navigation Controller just by adding a Navigation bar at the top?
sure
in viewbase application, u can create navigation controller
add the code in delegate.h
#interface test24AppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
test24ViewController *viewController;
UINavigationController *nav;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet test24ViewController *viewController;
#property (nonatomic, retain) IBOutlet UINavigationController *nav;
#end
add this delegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
nav=[[UINavigationController alloc]init];
[nav pushViewController:viewController animated:YES];
[self.window addSubview:nav.view];
[self.window makeKeyAndVisible];
return YES;
}
now it will work, u check using nslog(#"%#", self.navigationController); if the result is null then u have problem still.

Should I put my UITabBarController outside the App Delegate?

I followed an example from "Beginning iPhone 3 Development" which puts the code for the main view controller, a Tab Bar, in the delegate method. Is this the correct place to put this or should it be in a separate .h and .m file? All my subviews are in separate files so I'm wondering if I should have my tab bar view controller code in a separate file also.
Also, for the subviews I call ViewDidLoad as normal but there is no ViewDidLoad in the delegate method, I guess because it's of type NSObject and not UIViewController. Should I change the delegate to a type UIViewController so I can call ViewDidLoad?
Thanks, code samples of my existing app are below.
Header file for Delegate:
#import <UIKit/UIKit.h>
#interface MyAppDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate> {
UIWindow *window;
UITabBarController *rootController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UITabBarController *rootController;
#end
Beginning of Delegate implementation file
#import "MyAppDelegate.h"
#implementation MyAppDelegate
#synthesize window;
#synthesize rootController;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Add the tab bar controller's current view as a subview of the window
[window addSubview:rootController.view];
[window makeKeyAndVisible];
}
Is this the correct place to put this or should it be in a separate .h and .m file?
Should I change the delegate to a type UIViewController so I can call ViewDidLoad?
no this is your initial load point, not a view controller. Even if you change its type, the view did load method will not be called, the app delegate is not a view controller. It is here you load your initial view controller. UITabbar (according to the doco) "This class is not intended for subclassing." see here. (so no .h and .m file, what would you derive from?) you should not need to subclass, as you will get your viewdidload method for each of the views you put in your tab bar.