SACC

/ / Navigation

Part 1
Part 2
Part 3
Part 4
Part 5

/ / BUTTON Fun



The Model View Controller divides up functionality into distinct categories
  1. Model: the classes that hold the applications data
  2. View: Windows, controls and other elements to interact with
  3. Controller: Binds the model and view together and is the application logic that decides how to handle user's inputs

Any object you write should be identifiable as belonging in one of the three caategories. An object that implements a button should not contain code to process data when that button is pressed. This way your button can be reused.

Your controller component will typically be comprised of classes that you create and that are specific to your application. Controllers can be custom classes (NSObject subclasses), but generally they are subclasses of either UIKit or UIViewController.


What you are going to do

You will create and connect outlets and actions, implement view controllers and use application delegates. You will trigger actions and change the text of a label at runtime.


Part 1

Creating an outlet that points to a label where this outlet will allow you to change the text of a label. You will also create a method buttonPressed: that will fire when one of your two buttons is pressed. buttonPressed: will also set the label's text to show the user that a button was pressed.
  1. Open Xcode and create a new project


  2. Select application under the iPhone icon on the left


  3. In the right panel select View-Based Application, then press Choose. Save the project as Button Fun.

    Does it matter what you name the project? Yup, it sure does.

    The actual name is important because this name will need to be descriptive of the application. The name will be used in the filenames for the code. For example, if you named your application Button_Fun, the name will be attached to files such as the delegate file and will be named Button_FunAppDelegate.


  4. Expand the classes folder. You should see the following:
    view_classes.png

    The controller class that is responsible for managing the view is called Button_FunViewController.

  5. Open Button_FunViewController.h in the Groups and files pane. Add the lines in red
    //
    //  Button_FunViewController.h
    //  Button Fun
    //
    //  Created by guest_emac_rear4 on 2/5/09.
    //  Copyright __MyCompanyName__ 2009. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    
    @interface Button_FunViewController : UIViewController {
    IBOutlet UILabel *statusText;
    
    }
    @property (nonatomic, retain) UILabel *statusText;
    -(IBAction) buttonPressed:(id) sender;
    
    @end
    

    Your controller class can refer to objects in the nib file by using the instance variable called IBOutlet. Think of the IBOutlet as a pointer that points to an object within the nib.

    Interface objects in the nib file can be set up to trigger special methods in your controller class. These methods are known as action methods.

    Outlets

    Outlets are instance variables that are declared using the keyword IBOutlet. A declaration of an outlet in your controller's header file might look like this:
    IBOutlet    UIButton   *myButton;
    

    IBOutlet tells Interface Builder that you are going to connect this instance variable to an object in the nib. Any instance variable that you create and want to connect to an object in the nib file must be preceded by the IBOutlet keyword.


    Actions

    Actions are methods that are part of your controller class. They are also declared with a special keyword, IBAction, which tells Interface Builder that this method is an action and can be triggered by a control.
    -(IBAction)doSomething:(id)sender;
    The actual name of the method can be anything you want it to be, but it must have a return type (IBAction), which is actually the same as that of a return type (void). Why is it the same as void? Because IBActions don't return a value.

    The control that triggers your action will use the sender argument to pass a reference to itself. If your action method was called because you pressed a button, the argument sender would contain a reference to the button you pressed.

    The second of the optional attributes, nonatomic, changes the way the accessor and mutator methods are generated. Use nonatomic to save overhead.


  6. Save the file


  7. Open Button_FunViewController.m to add Actions and Outlets to the implementation file.
    Add the code in red:
    //
    //  Button_FunViewController.m
    //  Button Fun
    //
    //  Created by guest_emac_rear4 on 2/5/09.
    //  Copyright __MyCompanyName__ 2009. All rights reserved.
    //
    
    #import "Button_FunViewController.h"
    
    @implementation Button_FunViewController
    @synthesize statusText;
    
    -(IBAction) buttonPressed:(id)sender{
    	NSString *title=[sender titleForState:UIControlStateNormal];
    	NSString *newText=[[NSString alloc] initWithFormat:
    					   @"%@ button pressed.", title];
    	statusText.text=newText;
    	[newText release];
    }
    
    
    /*
    // The designated initializer. Override to perform setup that is required before the view is loaded.
    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
        if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
            // Custom initialization
        }
        return self;
    }
    */
    
    /*
    // Implement loadView to create a view hierarchy programmatically, without using a nib.
    - (void)loadView {
    }
    */
    
    
    /*
    // Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
    - (void)viewDidLoad {
        [super viewDidLoad];
    }
    */
    
    
    /*
    // Override to allow orientations other than the default portrait orientation.
    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
        // Return YES for supported orientations
        return (interfaceOrientation == UIInterfaceOrientationPortrait);
    }
    */
    
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
        // Release anything that's not essential, such as cached data
    }
    
    
    - (void)dealloc {
    [statusText release];
        [super dealloc];
    }
    
    @end
    

    @synthesize tells the compiler to create the accessor and mutator methods. Without creating them, there are now two methods available to use:
    • statusText:
    • setStatusText:


    You also included the implementation of your action method that gets called when either button is pressed. Both buttons call the method, and the program tells them apart by looking at the sender.

    The last line included the releases the string (memory management).

    The very last line included releases the outlet. Because you implemented properties for each of these outlets and specified retain in that property's attributes, releasing it is correct and necessary. Interface Builder will use the generated mutator method when assigning outlets, and that mutator will retain the object that is assigned to it, so it is important to release the outlet to avoid memory leaking.


  8. Save the file


  9. Compile by pressing ⌘+B



Part 2