iphone app hangs in AppDelegate (?) - iphone

No nib/IB, so I've inserted "myAppDelegate" in main and deleted the reference to main.xib in info.plist. Debug continues nicely through all five tab controllers; they seem to have gotten properly loaded into the nav controller. In fact, control passes out of the last "}" in applicationDidFinishLaunching. But there was no (visible) response back at [window addSubview:[tabBarController view]]; and [window makeKeyAndVisible]; statements, much less to the loadView within the first tab (program execution never gets there). The last line is, UIApplication _performInitializationWithURL:sourceBundleID:]. I missed a step? I executed a step improperly?

Did you create an UIWindow instance in applicationDidFinishLaunching:?
window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
Also, the line you call UIApplicationMain should look like this:
int retVal = UIApplicationMain(argc, argv, #"UIApplication", #"YourAppDelegate");
where YourAppDelegate is the name of your AppDelegate class.

Related

pushViewController is not working

I'm fairly new to Objective-C and iPhone programming so I apologize if this is a newbie question. I have a simple application that needs to go from one view, to another. The first view is a UIViewController. I set up the xib file in IB (i.e. dragged some buttons onto the window) and hooked up all the buttons (which all work). I then created another xib file and class (also a UIViewController) and hooked them up. When a button is pressed in the first view I want to load the second view. Here's the code that is supposed to be pushing the view:
-(IBAction)createAccount:(id)sender{
CreateAccountViewController*acctView = [[CreateAccountViewController alloc] initWithNibName:#"CreateAccount" bundle:nil];
[self.navigationController pushViewController:acctView animated:YES];
[acctView release];
}
But this does nothing. When I put print statements in the createAccount method those are printed (I can click the button any number of times and it never crashes) but the acctView is never pushed. When I print out the value of self.navigationController it returns null. It's even stranger because if I present the acctView modally then it works.
-(IBAction)createAccount:(id)sender{
CreateAccountViewController*acctView = [[CreateAccountViewController alloc] initWithNibName:#"CreateAccount" bundle:nil];
[self presentModalViewController:acctView animated:YES];
[acctView release];
}
This works just fine, but I don't want to use the view modally. I'm completely lost here. In the past couple of hours I've come across a lot of posts saying to do something with a UINavigationController and hook that up to my view, but how do I do that? Any help is greatly appreciated! Thanks.
It seems you haven't created a UINavigationController for your app.
Best thing would be starting from scratch with a new Xcode project, taking care of choosing a Navigation Based application. In this way you will get almost everything already set up for you.
If you don't like this approach, you can create programmatically your UINavigationController. Here you find a tutorial for doing that.
If you prefer more straight-to-the-point instructions, here they are:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
MainPageDialog *overviewViewController = [[MainPageDialog alloc] initWithNibName:#"MainPage" bundle:nil];
self.navigation = [[[UINavigationController alloc] initWithRootController:overviewViewController] autorelease];
[overviewViewController release];
[window addSubview:[navigation view]];
[self.window makeKeyAndVisible];
return YES;
}
whereby self.navigation is a retained property in your appDelegate.
EDIT:
This answer was quite old, therefore an update:
If you are using ARC, you should be using a strong (vs. retain) property and you would not need the autorelease;
if you target iOS > 4.0 (which is also implied by the above point), you can use the rootViewController property in UIWindow and say:
MainPageDialog *overviewViewController = [[MainPageDialog alloc] initWithNibName:#"MainPage" bundle:nil];
self.window.rootViewController = [[[UINavigationController alloc] initWithRootController:overviewViewController] autorelease];
[overviewViewController release];
[window addSubview:[self.window.rootViewController view]];
[self.window makeKeyAndVisible];
without the need for any navigation property.

'Terminating app due to uncaught exception'.. it couldn't find MainWindow, which no longer exists

I deleted all my .xib files a while ago, and recently changed my identifier. Now its started giving me this error:
Terminating app due to uncaught
exception
'NSInternalInconsistencyException',
reason: 'Could not load NIB in bundle:
'NSBundle
(loaded)' with name
'MainWindow''
MainWindow was deleted a while ago, and removing MainWindow from deployment info means that I'm just given a black screen. This is the code i have in my app delegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[application setStatusBarStyle:UIStatusBarStyleBlackOpaque];
[window addSubview:navigationController.view];
[self.window makeKeyAndVisible];
return YES;
}
Am i missing something? I presume i should remove MainWindow but as i say, this is just giving me a black screen.
You are getting this error because the NSMainNibFile value is set in your Info.plist. It tells the OS to open that NIB file at launch. Since you're doing away with NIBs for some reason, you will have to fill in the holes that you've created by deleting the NIB file.
You've to delete the key from the Info.plist.
You have to make some changes in your main.m. Usually the MainWindow.xib contained the information about your application delegate but now you need to provide it. Find the line that reads int retVal = UIApplicationMain(argc, argv, nil, nil); and replace it with int retVal = UIApplicationMain(argc, argv, nil, #"yourDelegateClassName");
What you've done so far will instantiate the application delegate and your application:didFinishLaunchingWithOptions: will get called but your window isn't set yet as it was taken care of by the NIB file again. This will apply to all your outlets. Not only your `window.
You will have to make some additions to your application:didFinishLaunchingWithOptions: method like this,
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Instantiate Window
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Instantiate Root view controller
RootViewController * viewController = [[[RootViewController alloc] init] autorelease];
// Instantiate navigation controller
navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
[application setStatusBarStyle:UIStatusBarStyleBlackOpaque];
[window addSubview:navigationController.view];
[self.window makeKeyAndVisible];
return YES;
}
The above method is just a template and must be modified to your requirement.

How to remove view from window?

I am using Cocos2D for my main framework. In some cases, I want Cocos2D to load a nib file and have that be the view:
window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
TargetPlayerViewController *myController = [[TargetPlayerViewController alloc]initWithNibName:#"TargetPlayerViewController" bundle:nil];
[window addSubview:[myController view]];
[window makeKeyAndVisible];
This works as expected, and shows the TargetPlayerViewController. Wonderful!
What I need to know is: once that view has been loaded, how can I have the view remove itself? I've tried a few different ways, but all of them result in the program crashing.
To test I have a button on the view set up which triggers this method:
- (IBAction)GTFOnow:(id)sender {
NSLog(#"GFTO");
//window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
//[self.view removeFromSuperview];
//[window makeKeyAndVisible];
}
GTFOnow is a method in TargetPlayerViewController. When it is called, the current subview (that was called in the Cocos2D code above) should be removed from the window.
First of all, you shouldn't create a new window just because you want to remove a subview. Secondly, whatever else happens, this shouldn't cause the app to crash. In which class do you have the GTFOnowmethod? I suppose in the TargetPlayerViewController class?

Why doesn't this released view controller cause a crash when messaged

- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Create the navigation and view controllers
RootViewController *rootViewController = [[RootViewController alloc]
initWithStyle:UITableViewStylePlain];
UINavigationController *aNavigationController = [[UINavigationController alloc]
initWithRootViewController:rootViewController];
self.navigationController = aNavigationController;
[aNavigationController release];
[rootViewController release];
[rootViewController setRegions:[Region knownRegions]];
// Configure and display the window
[window addSubview:[navigationController view]];
[window makeKeyAndVisible];
}
Here, in the above code the reference 'rootViewController' is used to send the message 'setRegions:', even after the object has been released in the previous line.
if it's wrong then how the simulator is running without any crash?
or
if it's right then, again how?, I couldn't see a difference between autorelease & release.
SOURCE:- http://developer.apple.com/iphone/library/samplecode/TableViewSuite/listing12.html
TO DOWNLOAD:- developer.apple.com/iphone/library/samplecode/TableViewSuite/index.html
The object held by rootViewController was retained by aNavigationController so its retain count is 2, and aNavigationController was retained when it is assigned to self.navigationController so its retain count is 2. So when you release rootViewController and aNavigationController, their retain counts drop to 1 each, so they are not collected, so you can still access them through their references.
Edit
Objects are only collected once their retain counts hit 0, and any reference to the objects is still valid, (even if the reference was released) until such time. Granted normally you don't want to rely on this and should make the call prior to releasing the object, but in this case it does work.

Loading a view controller & view hierarchy programmatically in Cocoa Touch without xib

It seems like all of the Cocoa Touch templates are set up to load a nib.
If I want to start a new project that's going to use a view controller, and load its view(hierarchy) programatically, not from a nib/xib, what are the steps to setting that up or adjusting a template.
I though all I had to do was implement -loadView, but I have trouble every time I try to do this.
It's reasonably simple to do completely programmatic user interface generation. First, you need to edit main.m to look something like the following:
int main(int argc, char *argv[])
{
NSAutoreleasePool *pool = [NSAutoreleasePool new];
UIApplicationMain(argc, argv, nil, #"MyAppDelegate");
[pool release];
return 0;
}
where MyAppDelegate is the name of your application delegate class. This means that an instance of MyAppDelegate will be created on launch, something that is normally handled by the main Nib file for the application.
Within MyAppDelegate, implement your applicationDidFinishLaunching: method similar to the following:
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
if (!window)
{
[self release];
return;
}
window.backgroundColor = [UIColor whiteColor];
rootController = [[MyRootViewController alloc] init];
[window addSubview:rootController.view];
[window makeKeyAndVisible];
[window layoutSubviews];
}
where MyRootViewController is the view controller for the primary view in your window. This should initialize the main window, and add the view managed by MyRootViewController to it. rootController is kept as an instance variable within the delegate, for later reference.
This should let you programmatically generate your user interface through MyRootViewController.
UIViews themselves do not have a hierarchy, UINavigationControllers do. So init one of those, and pop a UIViewController onto it's stack. This should do it, in the most basic way possible, with no XIB files at all. You should be able to build on this.
- (void)applicationDidFinishLaunching:(UIApplication *)application {
UINavigationController *navController = [[UINavigationController alloc] init];
UIViewController *viewController = [[UIViewController alloc] init];
// set the properties of viewController here, to make it look like you want
[navController pushViewController:viewController animated:NO];
[window addSubview:navController.view];
// Don't forget memory management
[navController release];
[viewController release];
[window makeKeyAndVisible];
}