How to properly create a root view controller? - iphone

After upgrading to xCode 4.2 I am getting the following warning...
Applications are expected to have a root view controller at the end of application launch
After reading as much as I could find on line about the RootViewController I am not sure whether I have created my root view controller properly. I created it a long time ago when I was first learning to program in xCode.
One question I have is it ok to name the root view controller something other than RootViewController. Every example I see now has it named RootViewController. I also see it synthesized in the app delegate like this...
#synthesize rootViewController = _rootViewController;
I do not understand what this is doing. Why not just...
#synthesize rootViewController;
In any event I changed the name of my root view controller to RootViewController and followed the example I found at cupsofcocoa.com. But even after the changes I am still getting the "...expected to have a root controller..." warning.
If someone has the time to take a look and let me know what I am missing, I have listed the the significant portions of my initialization code below.
Thanks,
John
//RootViewController.h
#import <UIKit/UIKit.h>
#interface RootViewController : UIViewController {
}
#end
.
//RootViewController.m
#import "RootViewController.h"
#import "JetLoggerAppDelegate.h"
#implementation RootViewController
#end
.
//JetLoggerAppDelegate.h my app delegate
#import <UIKit/UIKit.h>
#class RootViewController;
#interface JetLoggerAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
RootViewController *rootViewController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet RootViewController *rootViewController;
#end
.
//.m app delegate
#import "JetLoggerAppDelegate.h"
#import "RootViewController.h" //I don't think I need this here
#implementation JetLoggerAppDelegate
#synthesize window;
#synthesize rootViewController = _rootViewController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if ([launchOptions count] == 0) {
_rootViewController = [[RootViewController alloc] init];
self.window.rootViewController = self.rootViewController;
[window makeKeyAndVisible];
return YES;
}else{
[JLHelper showAlertWithTitle:#"" message:[NSString stringWithFormat:#"launchOptions: %#", launchOptions]];
}
return NO;
}
.
//main.m
#import <UIKit/UIKit.h>
int main(int argc, char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, #"JetLoggerAppDelegate");
[pool release];
return retVal;
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if ([launchOptions count] == 0) {
_rootViewController = [[RootViewController alloc] init];
self.window.rootViewController = self.rootViewController;
**[window addSubview:_rootViewController.view];**
[window makeKeyAndVisible];
return YES;
}else{
[JLHelper showAlertWithTitle:#"" message:[NSString stringWithFormat:#"launchOptions: %#", launchOptions]];
return NO;
}
return nil;
}
Put return NO inside else statement and on the end put return nil; Hope this help.

Applications are expected to have a root view controller
Replace in AppDelegate
[window addSubview:[someController view]];
to
[self.window setRootViewController:someController];

Related

screen not starting on iphone application

I am starting an iPhone application, and I can't seem to get the main screen started. Here is my delegate.h file:
#import <UIKit/UIKit.h>
#class MainViewController;
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (retain, nonatomic) MainViewController *mainViewController;
#end
and here is my implementation file(at least the beginning):
#import "AppDelegate.h"
#import "MainViewController.h"
#implementation AppDelegate
#synthesize window = _window;
#synthesize mainViewController = _mainViewController;
- (void)dealloc
{
[_window release];
[_mainViewController];
[super dealloc];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
MainViewController *aViewController = [[MainViewController alloc] initWithNibName:#"MainViewController" bundle:nil];
[self setMainViewController:aViewController];
[aViewController release];
self.window.rootViewController = self.mainViewController;
[self.window makeKeyAndVisible];
return YES;
}
When I try to run the app, just a black screen appears, and even after waiting a long time, the screen won't show the contents of my MainViewController.xib file...
Any ideas?
Main XIB of your application is MainWindow.xib. (It can be selected in project settings).
It contains app delegate, window and mainViewController (BTW, it should be better connected from XIB, not created manually in application:didFinishLaunching) connected to app delegate.
Check the connections.

DidFinishLaunching problem in application of iphone

Hello
I have problem with didFinishLaunching methods. I am really getting confused about what was the problem and that's why I pasted all my code. The problem was the application didn't launch, it crashed, and it show me this message in console:
**[Demo1AppDelegate setMapViewController:]: unrecognized selector sent to instance 0x5649a30
2011-05-25 14:17:58.724 Demo1[10630:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Demo1AppDelegate setMapViewController:]: unrecognized selector sent to instance 0x5649a30'**
I am using this code
In Demo1appDelegate.h file
#import <UIKit/UIKit.h>
#import "MapViewController.h"
#interface Demo1AppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
MapViewController *mapViewController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#end
And in
Demo1AppDelegate.m file
#import "Demo1AppDelegate.h"
#interface Demo1AppDelegate ()
#property (nonatomic, retain) MapViewController *mapViewController;
#end
#implementation Demo1AppDelegate
#synthesize window;
#pragma mark -
#pragma mark Application lifecycle
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
MapViewController *viewController = [[MapViewController alloc] init];
self.mapViewController = viewController;
[viewController release];
[window addSubview:self.mapViewController.view];
[window makeKeyAndVisible];
return YES;
}
- (void)dealloc {
[mapViewController release];
[window release];
[super dealloc];
}
#end
I think
self.mapViewController = viewController;
is the problem. You do not have #synthesize for mapViewController. So you cannot access through self
Or another option is to try this
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
mapViewController = [[MapViewController alloc] init];
[window addSubview:mapViewController.view];
[window makeKeyAndVisible];
return YES;
}
You need to implement UIApplication
change
#interface Demo1AppDelegate : NSObject
to
#interface Demo1AppDelegate : NSObject < UIApplicationDelegate>
This will solve your problem
the problem is in this line self.mapViewController = viewController;
you forgot #synthesize mapViewController;
Synthesize your map view controller.
You have to #synthesize mapViewController; in Demo1AppDelegate.m
You should also add [mapViewController release]; in the dealloc method of Demo1AppDelegate.m (with mapViewController being an instance variable).
Add delegate as follows ... This might be the issue :
#interface Demo1AppDelegate : NSObject <UIApplicationDelegate>
Try adding
#class MapViewController
before #implementation Demo1AppDelegate in Demo1AppDelegate.h
Hey! Where you add the subview
[window addSubview:self.mapViewController.view]; [window makeKeyAndVisible];
Try without "self"
[window addSubview:mapViewController.view]; [window makeKeyAndVisible];
Just a flying guess.

Go to another view (UIViewController) from within UIViewController

A newbie Objective C question. Im trying to programmaticly change view from another view. But I only succeed in activating the tab button in the tabbarcontroller.
In my ViewDidLoad I have a condition that if thats not met, load the second view instead.
Is there any kind soul that can help out a Objective-C beginner? I have googled and search stackoverflow for the answer but with no luck.
FirstViewController.h
#interface FirstViewController : UIViewController {
some variables
}
some #properties
FirstViewController.m
#import "FirstViewController.h"
#implementation FirstViewController
- (void)viewDidLoad
{
if(condition is met) {
[self.tabBarController setSelectedIndex:1];
}
}
In my AppDelegate.h
#import <UIKit/UIKit.h>
#interface otpAppDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate> {
UIWindow *window;
UITabBarController *tabBarController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
#end
AppDelegate.m
#implementation otpAppDelegate
#synthesize window;
#synthesize tabBarController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[self.window addSubview:tabBarController.view];
[self.window makeKeyAndVisible];
tabBarController = [[UITabBarController alloc] init];
[tabBarController setDelegate:self];
return YES;
}
Edit!
I found a solution to my problem.
int selectedindex = 1;
self.tabBarController.selectedIndex = selectedindex;
UIViewController *tempvc = [[self.tabBarController viewControllers] objectAtIndex:selectedindex];
[self.view removeFromSuperview];
[self.view addSubview:tempvc.view];
Did the trick.
Try setting the index for the tabBarController instance of the app delegate like yourAppDelegate.tabBarController
If you are using tabBarController as IBOutlet , there is no need to allocate it in your app delegate. Please remove these code from your appDelegate method (application: didFinishLaunchingWithOptions)..
tabBarController = [[UITabBarController alloc] init];
[tabBarController setDelegate:self];

Table and normal view inside of Tab Bar. Cannot see text on Bars

I am attempting to create an app where there is a tab bar on the bottom, and the first tab is supposed to be labeled "Bets" and the second is to be labeled "Settings". However, I attempted to change it in IB but it seems as though something is blocking the text from being seen, although you can see the bar and buttons at the bottom
DollarBetAppDelegate.h
#import <UIKit/UIKit.h>
#import "User.h"
#interface DollarBetAppDelegate : NSObject <UIApplicationDelegate,
UITabBarControllerDelegate> {
UIWindow *window;
UITabBarController *tabBarController;
UINavigationController *navController;
User *main;
}
#property (nonatomic,retain)User *main;
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
#end
DollarBetAppDelegate.m
#import "DollarBetAppDelegate.h"
#import "BetsViewController.h"
#import "SettingsViewController.h"
#import "User.h"
#import "Bet.h"
#implementation DollarBetAppDelegate
#synthesize window;
#synthesize tabBarController;
#synthesize main;
#pragma mark -
#pragma mark Application lifecycle
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
main = [[User alloc]init];
Bet *bet;
bet = [[Bet alloc]init];
NSLog(#"bet.betDesc = %# \n", bet.betOwner);
[main.betArray addObject:(Bet*)bet];
// Add the tab bar controller's view to the window and display.
BetsViewController *bvc = [[BetsViewController alloc] init];
SettingsViewController *svc = [[SettingsViewController alloc]init];
bvc.mainUser = main;
navController = [[UINavigationController alloc] initWithRootViewController:bvc];
[bvc release];
tabBarController.viewControllers = [NSArray arrayWithObjects:navController, svc,
nil];
[navController release];
[svc release];
[self.window addSubview:tabBarController.view];
[self.window makeKeyAndVisible];
return YES;
}
#pragma mark -
#pragma mark Memory management
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
/*
Free up as much memory as possible by purging cached data objects that can be recreated
(or reloaded from disk) later.
*/
}
- (void)dealloc {
[tabBarController release];
[window release];
[super dealloc];
}
#end
This is the end result when compiled
http://i55.tinypic.com/2zduf7c.png
If any other files are needed, let me know.
I appreciate any input.
From the UITabBarController class reference:
"If you do not provide a custom tab bar item for your view controller, the view controller creates a default item containing no image and the text from the view controller’s title property."
Your view controllers (BetsViewController and SettingsViewController) should set the title property in the initializer method.

Load different initial view based on application preferences?

I have a preference that, when set, forces my application to perform some synchronization on startup.
Can I use IB to display a different initial view based on this setting?
Is there a standard way to enable this behavior?
Assuming you have a property on your app delegate that is set during your synchronization, in the initial view controller's initWithNibNamed: method check the value synced by the app delegate and load the appropriate nib by calling [super initWithNibNamed:#"thisNibInsteadOfThatNib"];
EDIT: Show code to launch a different view depending on some condition at launch
// AppDelegate.h
#import <UIKit/UIKit.h>
#interface AppDelegate : NSObject <UIApplicationDelegate>
{
UIWindow *window;
UIViewController *firstViewController;
}
#property {nonatomic, retain} UIWindow *window;
#end
// AppDelegate.m
#import AppDelegate.h
#import ViewControllerOne.h
#import ViewControllerTwo.h
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
BOOL shouldLoadViewOne = \\ some value from preferences
if (shouldLoadViewOne) {
firstViewController = [[ViewOneController alloc] initWithNibName:#"ViewOneController" bundle:nil];
} else {
firstViewController = [[ViewTwoController alloc] initWithNibName:#"ViewTwoController" bundle:nil];
}
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:firstViewController];
[window addSubView:[navController view]];
[window makeKeyAndVisible];
return YES;
}
EDIT 2:
Make use of NSClassFromSting() and save the name of the firstViewController to load in the preferences.
// AppDelegate.h
#import <UIKit/UIKit.h>
#interface AppDelegate : NSObject <UIApplicationDelegate>
{
UIWindow *window;
id firstViewController;
}
#property {nonatomic, retain} UIWindow *window;
- (NSString *)firstViewControllerName;
#end
// AppDelegate.m
#import AppDelegate.h
#import ViewControllerOne.h
#import ViewControllerTwo.h
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSString *viewControllerName = [self firstViewControllerName];
firstViewController = [[NSClassFromString(viewControllerName) alloc] initWithNibName:viewControllerName bundle:nil];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:firstViewController];
[window addSubView:[navController view]];
[window makeKeyAndVisible];
return YES;
}
- (NSString *)firstViewControllerName
{
NSString *defaultViewController = #"ViewOneController";
NSString *savedFirstViewController = // string retrieved from preferences or other persistent store
if (!savedFirstViewController)
return defaultViewController;
return savedFirstViewController;
}