[Tutorial] How to set the view and how to switch between 2 views

Discussion in 'iOS Development' started by bamhm182, May 27, 2009.

  1. bamhm182

    bamhm182 Member

    Joined:
    Mar 2, 2009
    Messages:
    545
    Likes Received:
    0
    Device:
    3G iPod touch
    Apparently, I'm doing this horribly wrong. It would probably be wise to not follow this tutorial until this warning is gone. I will remove it once I figure out what I'm doing.

    Alright, so, I wasn't sure how to set the view when you chose the Window-based application project, so I thought I'd figure that out. Than I wanted to continue working on figuring out why I was getting the Bad Access error when trying to implement a button that would send me back to the first view.

    After playing around in Xcode for a few hours, I managed to find out how to do both. I've included the source code with a readme for those who want to see exactly what I did.

    So, when you start a new window-based application, you can't simply add a new xib and expect it to show. The first section of this tutorial will show you how to add a primary xib to your application. You could also follow this tutorial if you want to change the name of your primary xib, or switch the primary xib to a different file.

    How to add/change the first view that you're shown:

    To demonstrate, lets create a new project with the "Window-Based Application" template. Name it whatever you like.

    The first thing you'll want to do is open the classes folder and hit ⌘+N and create a UIViewController Subclass for you first screen. Make sure to check the "With XIB for user interface" checkbox. Again, name it whatever you want. I named mine "FirstPageViewController" for easy reference. You'll want to drag the newly created .xib file from the classes folder to the resources folder.

    Open your AppDelegate.h file and add the lines with comments above them. Make sure that if you used a name other than "FirstPageViewController" for your first page's files that we just created, you replace "FirstPageViewController" with your file's name.:

    Code:
    #import <UIKit/UIKit.h>
    
    //add a class for the first page you want to be shown.
    @class FirstPageViewController;
    
    @interface Test_AppAppDelegate : NSObject <UIApplicationDelegate> {
        UIWindow *window;
    	//add a view controller with the name of the first page, followed by *viewController or any other name that you find suitable.
    	FirstPageViewController	*viewController;
    }
    
    @property (nonatomic, retain) IBOutlet UIWindow *window;
    //give the First Page a property.
    @property (nonatomic, retain) IBOutlet FirstPageViewController *viewController;
    
    @end
    Now that we've got that set. Open your AppDelegate.m folder and again, add the lines under those that are commented out:

    Code:
    #import "Test_AppAppDelegate.h"
    //import the First Page's ViewController.h
    #import "FirstPageViewController.h"
    
    @implementation Test_AppAppDelegate
    
    @synthesize window;
    //synthesize the viewController.
    @synthesize viewController;
    
    - (void)applicationDidFinishLaunching:(UIApplication *)application {
    	//add a Subview for the viewController
    	[window addSubview:viewController.view];
        [window makeKeyAndVisible];
    }
    
    - (void)dealloc {
    	//release the viewController.
    	[viewController release];
        [window release];
        [super dealloc];
    }
    
    @end
    Now that we've got everything set up, go into the resources folder and double click the MainWindow.xib file to open it in Interface Builder.

    You should be presented with 4 pre-created files ( File's Owner, First Responder, App Delegate, and Window)

    You're going to want to add a View Controller from the "Controllers" folder. Click on the new View Controller and hit ⌘+1 to open the Attributes Inspector. You'll want to set the NIB Name to the name of your first page. In my example, I changed it to "FirstPageViewController".

    Now click File's Owner and hit ⌘+2 to open the Connections Inspector. Delete all outlets, excluding the delegate, by clicking the little x next to each of them.

    Open the App Delegate file and make sure that the Connections Inspector(⌘+2) is still open. Set the following by dragging from the circle on the right to its destination:

    Code:
    window - window
    viewController - The newly added View Controller(In my example, "FirstViewPageViewController")
    delegate - File's Owner(it should still be there, however, it never hurts to double check)

    Now that we've got MainWindow.xib set. You'll want to open the xib we created and moved to the resource file. Add something that will allow you to identify that it is the First Window. Something like a Label(Inputs & Values folder) saying "This is the First View" will work.

    You should now be able to build and run your application and be presented with the label we just set! If it doesn't work, go back and check for any mistakes. Now that we have our first view set up, we can now add the ability to switch between 2 views.

    How to switch between 2 views:

    Add a new UIViewController Subclass for the second page, just as we did for the first page in the beginning of the tutorial. Make sure the .m and .h files are in the Classes folder, and the .xib folder is in the Resources folder. I named mine "SecondPageViewController" for easy reference.

    Open the .h file for the first page(FirstPageViewController) and add the lines that are proceeded by comments:

    Code:
    #import <UIKit/UIKit.h>
    
    //add the class for the page you're going to.
    @class SecondPageViewController;
    
    @interface FirstPageViewController : UIViewController {
    	//add a Button for the button that will switch to the 2nd view.
    	IBOutlet	UIButton	*view2Button;
    }
    
    //add properties for the button that will switch to the 2nd view.
    @property (nonatomic, retain) UIButton	*view2Button;
    
    //add an IBAction for when the button is pressed, we will set in the corresponding .m file.
    - (IBAction)view2ButtonPressed:(id)sender;
    
    @end
    You'll also need to add some code to the First Page's .m file:

    Code:
    #import "FirstPageViewController.h"
    //import the Second Page's .h file
    #import "SecondPageViewController.h"
    
    @implementation FirstPageViewController
    //synthesize the button used to switch to the 2nd view.
    @synthesize	view2Button;
    
    //add the IBAction that was set in the .h file and tell it to load the 2nd view.
    - (IBAction)view2ButtonPressed:(id)sender;
    {
    	FirstPageViewController  *firstView = [[FirstPageViewController alloc] initWithNibName:@"FirstPageViewController" bundle:[NSBundle mainBundle]];
    	SecondPageViewController *secondView = [[SecondPageViewController alloc] initWithNibName:@"SecondPageViewController" bundle:[NSBundle mainBundle]];
    	[self.view addSubview:secondView.view];
    	[firstView release];
    }
    
    //LOOK HERE! The code above is what is used to switch to the second page.
    //As you can see, we've got a reference for the page you're on(FirstView)
    //and the page you're going to(SecondView) This allows the bottom 2 lines
    //of code to know what they're supposed to do. The addSubview command
    //tells the application to load the view that we've referenced as
    //"secondView" in the code above. You'll than want to "release" the view
    //you're leaving since it's no longer needed.
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
    }
    
    - (void)viewDidUnload {
    }
    
    - (void)dealloc {
        [super dealloc];
    }
    
    @end
    You're going to want to add the same type code, but referencing to the first page and its files. Look at the code below if you get lost:

    Second Page's .h file:
    Code:
    #import <UIKit/UIKit.h>
    
    //add the class for the page you're going to.
    @class FirstPageViewController;
    
    @interface SecondPageViewController : UIViewController {
    	//add a Button for the button that will switch to the 1st view.
    	IBOutlet	UIButton	*view1Button;
    }
    
    //add properties for the button that will switch to the 1st view.
    @property (nonatomic, retain) UIButton	*view1Button;
    
    //add an IBAction for when the button is pressed, we will set in the corresponding .m file.
    - (IBAction)view1ButtonPressed:(id)sender;
    
    @end
    Second Page's .m file:
    Code:
    #import "SecondPageViewController.h"
    //import the First Page's View Controller .h file
    #import "FirstPageViewController.h"
    
    @implementation SecondPageViewController
    //synthesize the button used to switch to the 1st view.
    @synthesize view1Button;
    
    //add the IBAction that was set in the .h file and tell it to load the 1st view. Make sure to tell it to release the second
    	//view or else it won't work.
    - (IBAction)view1ButtonPressed:(id)sender;
    {
    	FirstPageViewController  *firstView = [[FirstPageViewController alloc] initWithNibName:@"FirstPageViewController" bundle:[NSBundle mainBundle]];
    	SecondPageViewController *secondView = [[SecondPageViewController alloc] initWithNibName:@"SecondPageViewController" bundle:[NSBundle mainBundle]];
    	[self.view addSubview:firstView.view];
    	[secondView release];
    }
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
    }
    
    - (void)viewDidUnload {
    }
    
    
    - (void)dealloc {
        [super dealloc];
    }
    
    @end
    Now that we've got all the code that we needed added, it is time to go back into Interface Builder.

    Make sure everything is saved and double click on the xib for the First Page to open it in Interface Builder.

    You'll want to remove the label we added earlier and replace it with a rounded button (Inputs & Values folder) and name the button something like "Switch to View 2" so you know what it does. Click on the "File's Owner" file and open Connections Inspector. (Ω+2) You'll see 2 values for the code we just added in the First Page's .h/.m files. They should be called "view2Button" under Outlets and "view2ButtonPressed" under Received Actions. Drag from the circle to the button we just created for both of the new outlets. When you drag from "view2ButtonPressed" to the button, you'll be presented with a list. You want to choose "Touch Up Inside" from this list. Touch Up Inside tells the button that you want the action to happen after you let go of the button after pressing inside of it.

    Now that we've got the First Page set. Open the Second View's xib and do the same thing. However you'll want to reference the first page.

    - Add a button with something like "Switch to View 1" as the title.
    - Open File's Owner and connect view1Button and view1ButtonPressed to the newly added button. Make sure to select Touch Up Inside.

    Now you will be able to save everything. Build and run the app, and you should be presented with an app that allows you to switch between 2 views at the click of a button.

    This is useful for things like back buttons or buttons that take you to a different screen.

    I hope this helps some people out!

    Here's the source code:
    http://www.[PIRACY.mf].com/?2athmyniznx
  2. SkylarEC

    SkylarEC Super Moderator Emeritus Staff Member

    Joined:
    Sep 19, 2007
    Messages:
    6,658
    Likes Received:
    125
    If you "don't feel like writing a tutorial," don't advertise your thread as a tutorial.
  3. JoshuaCaputo

    JoshuaCaputo New Member

    Joined:
    Aug 2, 2008
    Messages:
    605
    Likes Received:
    0
    Device:
    iPod touch
    True, I too did this a few times but I see it really helps no1, if no1 knows whats in the file u attached you wants to download it. Especially if its on [PIRACY.mf] rather than uploading it here :p
  4. bamhm182

    bamhm182 Member

    Joined:
    Mar 2, 2009
    Messages:
    545
    Likes Received:
    0
    Device:
    3G iPod touch
    Fair enough. Like I said, I wrote it in the source code. However, yesterday I was ridiculously exhausted. Now, I'm awake though, so I'll gladly edit my post. :)

    EDIT: Just finished writing the tutorial. That's a long post!
  5. SkylarEC

    SkylarEC Super Moderator Emeritus Staff Member

    Joined:
    Sep 19, 2007
    Messages:
    6,658
    Likes Received:
    125
    Zomg. Run your app in Instruments, please. What you have created is a memory nightmare.

    : (
  6. bamhm182

    bamhm182 Member

    Joined:
    Mar 2, 2009
    Messages:
    545
    Likes Received:
    0
    Device:
    3G iPod touch
    crap. >< Will do.
  7. Just_For_Now

    Just_For_Now Active Member

    Joined:
    Mar 21, 2009
    Messages:
    2,017
    Likes Received:
    1
    Device:
    4G iPod touch
    Its more like [self.view addSubview:view.view];
    but there are other ways to do it.
  8. bamhm182

    bamhm182 Member

    Joined:
    Mar 2, 2009
    Messages:
    545
    Likes Received:
    0
    Device:
    3G iPod touch
    Either I have no idea what I'm doing, or you're not talking about memory leaks, or both. I think I've run tests in instruments, and I can't find any memory leaks.

    EDIT: Ah, there we go, I needed to be looking at ObjectAlloc. Yeah, that's horrid. I've figure it out. Thanks for the tip.
  9. SkylarEC

    SkylarEC Super Moderator Emeritus Staff Member

    Joined:
    Sep 19, 2007
    Messages:
    6,658
    Likes Received:
    125
    Here's how to do what you're trying to do.
    1. Create a view controller called RootViewController.
    2. Add the RootViewController's view as your window's main view.
    3. In your RootViewController, create both if your view controllers for the "switching views."
    4. Still in RootVieeController, set one of those views ad a subview of self.view.
    5. Still in RootViewController, create your switching button. Add that as a subview if your current view controller's view.
    6. Still in RootViewController, create a selector that fires when that button is pressed. REPLACE (id)sender WITH (UIButton *)button.
    7. In that method the button calls, figure out which view is showing, remove it from superview and add the other view controller's view as a subview of self.view. Remove the button using the button variable you set up from it's superview and add it a a subview of the new view.
    8. If you want, and I highly recommend this, add in a UIView transition or a CATransition to make your transition to the new view nice and polished.


    There's no reason to dealloc and recreate either if these viewcontrollers if you don't want to. Anf if you are frequently switching, I don't recommend it.

Share This Page