I was trying to create a tab bar based application from scratch but I'm having some issues. Basically I have my AppDelegate.h, AppDelegate.m and a MainView.xib. In the the .h file I have:
#interface AppDelegate : UIResponder <UIApplicationDelegate, UITabBarControllerDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) IBOutlet UITabBarController *tabBarController;
#end
In My .m I have:
#synthesize window = _window;
#synthesize tabBarController = _tabBarController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Override point for customization after application launch.
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
And in my xib file I have my files owner as a class of Appdelegate and I have my outlet from there hooked up with a Tab Bar Controller. The problem is that my controller is returning null and thus isn't being set as the rootViewController. What step/idea am I missing in setting up my app? Thanks in advance!
EDIT FIXED: Since I was starting from a empty application I didn't have 'Main nib file base name' set, so I just had to set it to the nib I was trying to load.
You need to create the view controllers that will be accessed through the tabs on your Tab Bar Controller. Then you must assign them to the viewControllers property of the Tab Bar. You can do this just before setting the Tab Bar as the window's rootViewController:
MyViewController1 *vc1 = [[MyViewController1 alloc] init];
MyViewController2 *vc2 = [[MyViewController2 alloc] init];
NSArray *controllers = [NSArray arrayWithObjects:vc1, vc2, nil];
self.tabBarController.viewControllers = controllers;
I hope it helps!
Normally the appDelegate object is not a subclass of UIResponder, but a subclass of NSObject.
Are you hooking the TabBar instance to the first responder in your xib file? take into account that this won't work as the first responder is only a proxy object and setting the class type to it won't cause an object to be instantiated.
Instead, create an AppDelegate object in your xib file and hook the TabBar to it.
Hope it helps.
Since I was starting from a empty application I didn't have 'Main nib file base name' set, so I just had to set it to the nib I was trying to load.
Related
I have been searching and experimenting on this for a while, but I just can't find out what I'm doing wrong.
I want to make an app with a menu, and from that menu, you can get to a TableViewcontroller with a title bar. I found out that, in order to get this title bar, you need to "insert" UITableViewController into a UINavigationController. this is where I'm stuck.
let's not mind / forget the menu from the app for now, because i know how to switch view controllers when user taps a button.
in my AppDelegate.m I have:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
TableViewController *tableView = [[UITableViewController alloc] initWithStyle:UITableViewStylePlain];
self.navController = [[UINavigationController alloc] initWithRootViewController:tableView];
self.window.rootViewController = navController;
[self.window makeKeyAndVisible];
return YES;
}
in my AppDelegate.h file I Have:
#interface AppDelegate : UIResponder <UIApplicationDelegate>{
UINavigationController *navcontroller;
}
#property (strong, nonatomic) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UINavigationController *navController;
I have 2 classer, UITableViewController and NavigationView.
In the UITableViewController, I made an array called tableRows:
tableRows = [[NSArray arrayWithObjects:#"1", #"2", nil] init];
the numberOfSectionsInTableView is set as 1 and the numberOfRowsInSection is set as return tableRows.count;
I left my NavigationView.m untouched, except that I tried to set a title in it.
in my NavigationView.xib, I tried to make the connection between the UITableViewController and the UINavigationController.
I added an NSObject, and changed its class to AppDelegate
I replaced the View for a UIWindow and connected the window property from my
AppDelegate.h to it
I added a UINavigationController and
connected it with the navController from my AppDelegate.h.
and last, I changed the class from the RootView from the
UINavigationController to UITableViewController.
Now my problem is, with or without the connections in IB, whatever I try to change in my table, or in the titlebar, it does not change when I run the app.
Does anybody know what I'm doing wrong? I'm using xcode 4.6, so lots of the tutorials I've checked are not very useful, because they are made with older versions of xcode. please help me, Thank you in advance!
in you AppDelegate replace this line
TableViewController *tableView = [[UITableViewController alloc] initWithStyle:UITableViewStylePlain];
with this
TableViewController *tableView = [[TableViewController alloc] initWithStyle:UITableViewStylePlain];
You're not creating an instance of TableViewController but instead UITableViewController so thus you're not getting any of your code executed. (You should have a compiler warning for this in your app delegate - make sure to heed those warnings). Likewise you're not loading the NavigationView nib anywhere - you're creating a navigation controller with the table as the root view controller. It's not clear what your objective for NavigationView is so I can't provide a recommendation for how to proceed. However, for the table view, change the following line in your app delegate
TableViewController *tableView = [[UITableViewController alloc] initWithStyle:UITableViewStylePlain];
to
TableViewController *tableView = [[TableViewController alloc] init];
In your table view xib, make sure File's Owner's class is set to be of class TableViewController (not UITableViewController). Right click on the table view and drag the circles next to 'data source' and 'delegate' to file's owner. Then right click file's owner and make sure the circle next to 'view' is connected to the table view. Save, clean, and run.
You might also find it very useful to checkout the free Sensible TableView framework. The framework will take your array and automatically generate all the table view cells, while managing all the details required to correctly setup the navigation controller. Hope this helps.
I am very new to iOS development and would appreciate if experts here would be able to help me with my problem. At the moment, my application is extremely basic and does nothing much. Prior to trying to add a tab bar to my existing view, things worked fine. I am not sure what I'm missing but nothing is showing when I run the simulation. I'll try my best to explain the structure of my application so that you guys can understand the problem better.
The following are currently present in the application...
FeedList: A UITableViewController embedded inside a UINavigationController.
FeedCell: A UITableViewCell created for FeedList.
FeedItemDetail: A UIViewController with a UIScrollView within it. User will be brought to this screen by tapping on a cell in FeedList.
Below are the codes for AppDelegate.h and AppDelegate.m. I would greatly appreciate it if someone is able to tell me why nothing is showing on my simulation screen. Thanks!
//AppDelegate.h
#import <UIKit/UIKit.h>
#import "FeedList.h"
#interface AppDelegate : NSObject <UIApplicationDelegate>
{
UIWindow *window;
FeedList *feedList;
UITabBarController *tabBarController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) FeedList *feedList;
#property (nonatomic, retain) UITabBarController *tabBarController;
- (void)customizeAppearance;
#end
//AppDelegate.m
#import "AppDelegate.h"
#implementation AppDelegate
#synthesize window, feedList, tabBarController;
// Entry point
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
tabBarController = [[UITabBarController alloc] init];
feedList = [[FeedList alloc] init];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:feedList];
tabBarController.viewControllers = [NSArray arrayWithObject:nav];
[window addSubview:tabBarController.view];
[window makeKeyAndVisible];
}
Update (problem solved)
I realized that after adding the line tabBarController.viewControllers = [NSArray arrayWithObject:nav]; things start to go haywire. After checking Apple's Documentation, the reason is because if the value of this property is changed at runtime, the tab bar controller removes all of the old view controllers before installing the new ones. It is therefore required that we set the new tab bar controller as the root view controller.
I agree with Dustin's comment, you should use the storyboard if you are starting off new. What I see wrong with your method, or different from typical anyway, is that you don't add tabBarController as subview you set the rootViewController of self.window like so:
// Entry point
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
tabBarController = [[UITabBarController alloc] init];
feedList = [[FeedList alloc] init];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:feedList];
tabBarController.viewControllers = [NSArray arrayWithObject:nav];
//******* This is my correction *******
window.rootViewController = tabBarController;
//******* *******
[window makeKeyAndVisible];
}
Of course there is no way to tell from the info you provided if your tableview is set up right so there is no guarantee this will display your table.
I am working on iOS 5. I am not able to find the navigation based application template formerly found in Xcode.
So what can I use instead?
If you want to start from scratch, start with a Single View Based project, then go to the storyboard and select the viewController, go to Editor > Embed in > Navigation Controller.
You need to use Master-Detail Application template. Choose Device Family from dropdown list as iPhone. After creating a project your appDelegate will contain UINavigationController instance.
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) UINavigationController *navigationController;
#end
and
#implementation AppDelegate
#synthesize window = _window;
#synthesize navigationController = _navigationController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Override point for customization after application launch.
MasterViewController *masterViewController = [[[MasterViewController alloc] initWithNibName:#"MasterViewController" bundle:nil] autorelease];
self.navigationController = [[[UINavigationController alloc] initWithRootViewController:masterViewController] autorelease];
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
return YES;
}
Use storyboard and drag a view controller into it. Then go Editor>Embed In>Navigation Controller.
Start with the Empty Application project. Add a UINavigationController.
This article, Creating a Navigation based iOS 5 iPhone Application using TableViews, will guide you. And this tutorial, Navigation Controllers and View Controller Hierarchies.
I have a root view controller which should load another view controller as soon as it is done loading (i.e. in the viewDidLoad method).
I am using the UINavigationController in order to push a new view controller onto the stack:
In my rootviewcontrollerappdelegate:
-(void) viewDidLoad{
LoginViewController* lvc = [[LoginViewController alloc]init];
[self.navigationController pushViewController:lvc animated:NO];
}
I have textfields and buttons in the view controller to be loaded. The above doesn't seem to work however...It loads just a blank grey screen and no UINavigation bar is present. If I comment out the second line (pushViewController line), then I see the navigation bar. So I think it is loading something, but the items in the view controller being loaded are not being shown...Any ideas why?
Check if navigationController is pointing to nil. If it does, try
[self.view addSubview:self.pushViewController.view]
I had the same problem and found the above solution here:
UIViewController -viewDidLoad not being called
Unless you're doing something tricky, you should be calling alloc on the LoginViewController class rather than a variable. Also, if you've set up LoginViewController in Interface Builder (as opposed to programmatically), you'll need to load it from an NIB:
LoginViewController *lvc = [[[LoginViewController alloc] initWithNibName:nil bundle:nil] autorelease];
[self.navigationController pushViewController:lvc animated:NO];
Have a look at initWithNibName:bundle: in the docs.
Not entirely sure what you are trying to achieve but when you instantiate LoginViewContoller it should probably look like this
LoginViewController* lvc = [[LoginViewController alloc]init];
Judging by the nature of your naming for your view controller, is your LoginViewController the first view controller for your UINavigationController?
If that is what you're trying to do, you should instead initialise your navigation controller with the LoginViewController as the root controller instead of pushing it onto the navigation stack.
UINavigationController has a method to do this:
- (id)initWithRootViewController:(UIViewController *)rootViewController
EDIT:
Well, one way you can go about it is like this.
In your application delegate .h file, you should have declared a UINavigationController.
#interface MyAppDelegate : NSObject <UIApplicationDelegate>
{
UINavigationController *navController;
}
#property (nonatomic, retain) UINavigationController *navController;
#property (nonatomic, retain) IBOutlet UIWindow *window;
#end
In your App Delegate didFinishLaunching:withOption: you can create an instance of your LoginViewController there, and use that to init your UINavigation controller as the root view controller
#import "LoginViewController.h"
#implementation MyAppDelegate
#synthesize navController;
#synthesize window = _window;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
LoginViewController *loginController = [[LoginViewController alloc] init];
navController = [[UINavigationController alloc] initWithRootViewController:loginController];
[loginController release];
[[self window] setRootViewController:navController];
[navController release];
[self.window makeKeyAndVisible];
return YES;
}
I probably have a typo here or there but that's one way I would go about doing it.
I'm a beginner with Xcode and Objective-C, i want to make a view controller in code without a nib file and shape it how i want. Currently with this very simple code I can't seem to even change the background color because of EXC_BAD_ACCESS.
I read on internet it is something with memory management but I can't seem to find the fix for this. Pieces of my code:
AppDelegate.h
#import <UIKit/UIKit.h>
#import "DefaultViewController.h"
#class DefaultViewController;
#interface AppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
UIViewController *rootViewController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UIViewController *rootViewController;
#end
AppDelegate.m
#synthesize window = _window;
#synthesize rootViewController = _rootViewController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UIViewController *rvc = [[DefaultViewController alloc] init];
self.rootViewController = rvc;
[rvc release];
[self.window addSubview:self.rootViewController.view];
// Override point for customization after application launch.
[self.window makeKeyAndVisible];
return YES;
}
- (void)dealloc
{
[_window release];
[_rootViewController release];
[super dealloc];
}
The view controller I made via, right click -> new file and UIViewController subclass without xib! In the loadView I only try this:
self.view.backgroundColor = [UIColor redColor];
The problem could be that the rootViewController doesn't have an initialized view. Hard to tell, since you don't show the code of the DefaultViewController. It could also be another error in DefaultViewController.
FWIW, you have two obsolete ivars:
#interface AppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
UIViewController *rootViewController;
}
You can delete these, since you synthesize _window and _rootViewController and never use the above.
There are a few issues with your code. But first the key problem you are getting EXC_BAD_ACCESS is because you are calling self.view.backgroundColor inside the loadView. If you override loadView, you must construct your view hierarchy inside the method. By not creating a view hierarchy in that method you are calling backgroundColor on a view that does not exist. Instead completely remove the loadView method or comment it out and move self.view.backgroundColor into the viewDidLoad method. (Remember even an empty loadView method will be a problem, you need to remove it or comment it out)
Second.. change your code to
self.rootViewController = rvc; to self.window.rootViewController = rvc;
BTW, once you add a view controller you don't need to add the view of the rootViewController as a subview to the window again. Assigning a view controller to the rootViewController property installs the view controller's view as the content view of the window.
Third. When you are initializing DefaultViewController you do
UIViewController *rvc = [[DefaultViewController alloc] init];
dont do that, instead do
DefaultViewController *rvc = [[DefaultViewController alloc] init];
Change the code so it's
self.window.rootViewController = rvc;
[self.window makeKeyAndVisible];
return YES;
What's inside your DefaultViewController? If you are not using a nib file, did you implement -(void)loadView ?
You should call:
UIViewController *rvc = [[DefaultViewController alloc]
initWithNibName:#"yournib" bundle:nil];
to load the NIB view. Otherwise, your rvc.view will be nil.
Sorry, I overlooked.
The answer is: you should not call self.view.backgroundColor = [UIColor redColor]; within - (void)loadView since self.view is nil firstly at this stage. He has to show that he has correctly created at least self.view = [[UIView alloc] init] in loadView.