views:

38

answers:

1

I am writing my first iPhone App, a test case before I write my life saving app to help me learn how things are done on this platform. So I used the standard ModelViewController widget and created my app. I put my UI on the default view and added all the glue code in the ViewController.m/.h files: event handlers, IBOutlet mappings to change my controls' state, etc. This all worked wonderfully and didn't take too long to do.

Now I want to add an info page to my application. I added an i button to my main page and mapped it to an empty handler, toggleCreditsOpen:, and then created a new view for my project, "info.xib". I opened interface builder and set up my view to my liking (though I would prefer if the credits could be loaded dynamically rather than directly in the view, I'll worry about that later as I'm pretty sure it's easy to change the text, and I just hope it's just as easy to load from a localized resource file, but that's not my question). I created a Done button in my info.xib and mapped that to another handler, toggleCreditsClosed. So now I have these two empty handlers: one when the info button is pressed, and one when the done button in the info window is pressed:

- (IBAction) toggleCreditsOpen: (id) sender {
    // ???
}

- (IBAction) toggleCreditsClosed: (id) sender {
    // ???
}

If anyone can explain what goes in these two functions, I will not be the only one grateful since I will put these instructions in an upcoming blog entry explaining how to do this so that people don't have to bash their heads against the table like me trying to put that final touch to their app: the credits!

A: 

First, you should have a separate view controller class for the info view (best practice). And there are different answers to your question depending on how you want to present the info view.

Assuming you have made another class for your info view controller, a standard way is to use presentModalViewController: animated:

- (IBAction) toggleCreditsOpen: (id) sender {
    InfoViewController *info = [[InfoViewController alloc] initWithNibName:@"info" bundle:[NSBundle mainBundle]];
    [self presentModalViewController:info animated:YES];
    [info release];
}

Move the other method to your InfoViewController class:

- (IBAction) toggleCreditsClosed: (id) sender {
    [self.parentViewController dismissModalViewControllerAnimated: YES];
}

So you will have to make two new files: InfoViewController.h, InfoViewController.m And you will have to set File's Owner in your info.xib to be of class InfoViewController (it's on the identity tab in inspector of File's Owner) and set the view outlet and the button action there as well.

vakio
Thanks for the advice. So, since you suggested that a new implementation file should be created, I did that: I created InfoViewController, with an associated .m file, .h file and a new .xib file from which I copied all my view settings in Interface builder.
TimeHorse
I then split the code into the files you suggested, uncommented the initWithNibName:bundle: method, modified your code to add the bundle parameter (as nil) and tried it out. Unfortunately, my application is able to allocate the InfoViewController but when it tries to call presentModalViewController:animated: it crashes without explanation. Ung, why must this be so obfuscated!
TimeHorse
Ah, was missing a framework for one of my widgets. Had to start gdb to see the error. Funny, that. So let me run a few more tests and if I can get this working I'll give you full credit!
TimeHorse
Ah, sorry. Was supposed to be initWithNibName:bundle: of course. Usually I put bundle:[NSBundle mainBundle] but if you put nil it means the same thing. Just a force of habit.
vakio