Navigation Within TabController - iphone

I am trying to use UITabController as may controller in my main window and add navigation controllers to some tab bar items.
For example, the first tab has a navigation controller with table view:
alt text http://www.freeimagehosting.net/uploads/f3ad987c86.png
The SettingsViewController is associated with its own NIB file, where a table view is defined. Within that xib file, I have a table view and set it to the outlet of SettingsViewController class property myTableView.
Here are my h files:
// header file for SettingViewController class
#interface SettingsViewController :
UIViewController <UITableViewDelegate, UITableViewDataSource> {
UITableView *myTableView;
// other codes vars
}
#property (nonatomic, retain) IBOutlet UITableView *myTableView;
// ...
#end
// header for main app delegate
#interface MainAppDelegate :
NSObject <UIApplicationDelegate, UITabBarControllerDelegate> {
UIWindow *window;
UITabBarController *tabBarController;
// ...
}
#property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
// ...
#end
In my SettingsViewController.xib file, through IB, I linked outlet myTableView to the xib's file owner, ie, SettingViewController class:
alt text http://www.freeimagehosting.net/uploads/e577d35137.png
The problem is that in the main xib file, for the SettingsViewController navigation, there is one outlet myTableView. I am not sure if I have to set this to somewhere?
The exception I get is "[UIViewController _loadViewFromNibNamed:bundle:] loaded the "SettingsViewController" nib but the view outlet was not set."

SettingsViewController already has a view property. Are you sure this one is hooked up in Interface Builder? (You probably want it to be hooked up to your UITableView.)

Related

Assign own View Classes to Storyboard

See this storyboard containing a Navigation View, Gestures, and a few Views.
Also within is a TabView, which contains an UIImageView and UITableViewController.
To apply my data to this TableView, I need to assign a Controller by using msExampleTableViewController.
The problem: the input/dropdown field removes entry after pressing Enter (like if this class is not assignable).
What is wrong here, and how can it best be done?
NA UITableViewController does assume that the root view will be a UITableView. When you combines UITableView with others controllers.. you can do in your Controller (ViewController in your case):
#interface YourViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
#property (nonatomic, assign) IBOutlet UITableView* tableView;
In Interface Builder set both the delegate and dataSource outlets of the table view to be equal to its superview's view controller (File's Owner)...
Now, Your view controller implementation should be the typical TableViewController implementation: cellForRowAtIndexPath, etc.

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];

Do I need to create variables and link IBOutlet for every UIVIew?

I have a View Controller that is swapping UIView objects in and out. There is the potential to have hundreds of different views, each with their own behaviors.
Within my current MainWindow.xib file I currently have:
File's Owner UIApplication
First Responder UIResponder
AppDelegate AppDelegate
-Cover Cover
Window UIWindow
Table of Contents TableOfContents
page1 Page1
page2 Page2
page...n Page...n
The AppDelegate declares the window and the viewController. It's pretty basic.
MainViewController.h
#import <UIKit/UIKit.h>
#class TableOfContents, Page1;
#interface MainViewController : UIViewController {
TableOfContents *tableOfContents;
Page1 *page1;
Page2 *page2;
Page...n *page...n;
}
#property (nonatomic, retain) IBOutlet TableOfContents *tableOfContents;
#property (nonatomic, retain) IBOutlet Page1 *page1;
#property (nonatomic, retain) IBOutlet Page2 *page2;
#property (nonatomic, retain) IBOutlet Page...n *page...n;
-(IBAction)funcGoToPage:(id)sender;
#end
MainViewController.m
#import "MainViewController.h"
#import "TableOfContents.h"
#import "Cover.h"
#import "Page1.h"
#import "Page2.h"
#import "Page...n.h"
#implementation MainViewController
#synthesize page1, page2, page...n tableOfContents;
#synthesize pageID, pagesPathFile, pagesPath;
-(IBAction)funcGoToPage:(id)sender{
//[[self view] removeFromSuperview];
[self.view addSubview:self.tableOfContents];
}
The corresponding UIView classes are pretty bare at the moment so I'll refrain from posting them.
Right now funcGoToPage is just bringing up tableOfContents. Eventually I'll have it go different places depending on what was clicked.
Currently each page is set up as an IBOutlet and linked from the MainViewController to the appropriate UIView in Interface Builder. Done this way each page will have to be set up as a variable and linked to in IB creating a hubub of variables, outlets and connections.
My question is: Is there a way to create these connections on the fly so that I can swap them in using my funcGoToPage function without setting them up as an IBOutlet?
When a nib is loaded all of its content is loaded. If you have lots of views in one nib you'll quickly run out of memory.
I would put each page in a seperate nib and then load the nib when required:
[[NSBundle mainBundle] loadNibNamed:#"nibNameWithoutExtension" owner:self options:nil];
For this to work:
add an IBOutlet, eg newPage, to whatever self refers to
set the File Owner in nibNameWithoutExtension to whatever self refers to
join the view in nibNameWithoutExtension to the newPage outlet of File Owner

Calling pushViewController on a UINavigationController does nothing (no crash)

I have a UINavigationController as one of the views inside a tab bar control. It looks fine, and I have a UIBarButtonItem that is supposed to load a subview. I have the button wired up to an IBAction that calls pushViewController but when I do this nothing happens. It doesn't crash or anything.. it just doesn't do anything. I've tried: using different view controllers as the subview (no luck). Does anybody have any suggestions? Here is my code:
Header file:
#import <UIKit/UIKit.h>
#import "FSSettings.h"
#import "MeasureSelector.h"
#import "Dashboard.h"
#interface DashboardNavigationController : UIViewController {
IBOutlet UINavigationController *navController;
IBOutlet UINavigationBar *navBar;
IBOutlet UIBarButtonItem *measureButton;
}
#property (nonatomic, retain) IBOutlet UINavigationController *navController;
#property (nonatomic, retain) IBOutlet UINavigationBar *navBar;
#property (nonatomic, retain) IBOutlet UIBarButtonItem *measureButton;
- (IBAction) showMeasureScreen:(id)sender;
#end
And the .m file containing the action:
// Displays the measure screen
- (IBAction) showMeasureScreen:(id)sender
{
NSLog(#"Loaded measure screen");
MeasureSelector *msel = [[MeasureSelector alloc] initWithNibName:#"MeasureSelector" bundle:nil];
[[self navigationController] pushViewController:msel animated:YES];
NSLog(#"Done.");
}
When I click the button nothing happens (but I do see the log messages). I can do this over and over with no ill effects, however.
The navigationController property of UIViewController refers to the nav controller of which the UIViewController is part of the hierarchy. If I understand the scenario correctly, DashboardNavigationController manages the view that is the container for the UINavigationController, so it makes sense that this property would be nil.
Use the outlet you created to access the nav controller from outside of the nav controller's hierarchy.

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.