Storyboard

This app has one application delegate, one view controller, and one view. The view contains one button. (Since a button is a view, there are actually two views.) The app also has a window, but we’re not interested in it now. These objects will be created with a storyboard. The user will do this by dragging icons off a pallet into the storyboard.

Source code in Board.zip

  1. main.m
  2. Class BoardAppDelegate
  3. Class BoardViewController
  4. Board-Info.plist
  5. MainStoryboard.storyboard

Two problems

An object contained in a storyboard file is called a storyboard file object (a term I invented myself). An object created by calling methods (alloc, init, etc.) in a .m file is called a normal object. How can a normal object get the address of a storyboard file object? Conversely, how can a storyboard file object call a method that belongs to a normal object? We will solve these problems with two macros.

Macros

A macro is a word that is changed into something else (or into nothing at all) by a word processor called the C preprocessor. The name of a macro is conventionally all uppercase. Examples we have seen, without being aware that they are macros, include the following.

  1. M_PI, which is changed into 3.14159265348979
  2. YES, which is changed into 1
  3. NO, which is changed into 0
  4. nil, which is changed into a zero of some data type

In a .h or .m file, the macros named IBOutlet and IBAction will catch the attention of the storyboard.

Outlets

An instance variable that is visible outside its class is called a property. A property that points to a storyboard file object is called an outlet. Its declaration is marked with the macro IBOutlet to tell the storyboard that the property is intended to be an outlet. For example, the application delegate might contain the following outlet, which points to a window that is a storyboard file object.

@property (strong, nonatomic) IBOutlet UIWindow *window;
The macro IBOutlet expands (i.e., is changed by the C preprocessor) into nothing at all.

#define	M_PI 3.14159265348979	//M_PI is a macro that expands into 3.14159265348979
#define IBOutlet		//IBOutlet is a macro expands into nothing at all.

Since the word IBOutlet expands into nothing, it has no effect on the Objective-C code. But we use it anyway because it marks a property that will eventually point to a storyboard file object.

Outlet documentation in

  1. Cocoa Fundamentals Guide

Actions

A method that should be called when a control is touched is called an action. Our first example of an action was the touchUpInside: method of class View in the Button app. An action always returns void (no value at all). But instead of declaring the action to return void, declare it to return IBAction. This macro expands into the word void, so the result is exactly the same. The macro tells the storyboard that the method is intended to be an action that is called by a control that is a storyboard file object.

- (void) someMethod {	//someMethod is probably initWithFrame:
	button = [[UIButton buttonWithType: UIButtonTypeRoundedRect];

	[button addTarget: self
		action: @selector(touchUpInside:)
		forControlEvents: UIControlEventTouchUpInside
	];
}

//The following method is an action.

- (IBAction) touchUpInside: (id) sender {
	NSLog(@"Button is pressed.");
}

Create the project

File → New → File…
Chose a template for your new project: Singe View Application
Next
Choose options for your new project:
Product name: Board
Organization name: nyuguest
Company identifier: edu.nyu.scps
Class Prefix: Board
Devices: iPhone
☑ Use Storyboards
☑ Use Automatic Reference Counting
☐ Include Unit Tests
Next
Create

Run the app. You should see a white view that does nothing.

In Xcode’s Project Navigator, open the Supporting Files folder and look in Board-Info.plist. Observe that the main storyboard file base name is MainStoryboard.

In the Project Navigator, double-click on the file MainStoryboard.storyboard. The panel to the right of the navigator is the outline view. The outline view should say

Board View Controller Scene
Board View Controller
 First Responder
 Exit

Click on the above triangle to see the view controller’s view. Select the view.

The right panel of Xcode is the Utilities panel. If you don’s see it, or if you’re not sure whether you’re seeing it, select
View → Uitilites → Show Attributes Inspector

At the top of the Utilities, the icon for the Attributes Inspector looks like a pentagonal home plate with two ears. Select this icon. Since we have selected the view controller’s view in Xcode’s outline view, the Attributes Inpector should display the attributes of the view.

Click on the rectange next to the word Background and make the view’s background yellow. Run the app.

Create a button

Keep the view controller’s view selected in the outline view. In the lower panel of the Utilities area, select the cube icon. In the drop-down menu below the cube, select Controls. Under the drop-down menu, drag the Round Rect Button into the yellow view and release it. You can reposition and resize the button, and double-click on its text to edit it. The Attributes Inspector will let you change the button’s colors.

Designate what method of what object will be called when the button is pressed

We will give the view controller a method named touchUpInside: and call it when the button is pressed. (Specifically, when the finger lifts off.)

To save space, hide the Utilities area. There are three buttons labelled View in the upper right corner of Xcode. Press the right button to hide the Utilities.

Show the assistant editor. There are three buttons labelled Editor in the upper right corner of Xcode. Press the middle button to show the editor. (To make the editor go away, you can press the box with the x in the upper right corner of the editor.) The assistant editor should display the file BoardViewController.h. (You can use the Project Navigator to select the file that the assistant editor displays.)

Control-drag from the button in the yellow view to the @interface of the BoardViewController.h in the assistant editor. You will see blue lines. Then release the control-drag to display the following popover.

Fill in the popover.

Connection: Action
Object: Board View Controller
Name: touchUpInside:
Type: id
Event: Touch Up Inside
Arguments: Sender
Connect

The @interface section of BoardViewController.h should now contain the declaration for a method named touchUpInside:.

@interface BoardViewController: UIViewController

- (IBAction) touchUpInside: (id) sender;
@end

And the @implementation section of BoardViewController.m should now contain an empty definition for the method.

- (IBAction) touchUpInside: (id) sender {
}

Insert some code that will verify that the method is called:

- (IBAction) touchUpInside: (id) sender {
	NSLog(@"Button is pressed.");
}

Give the view controller a pointer to the button

Control-drag from the button in the yellow view to the @interface of the BoardViewController.h in the assistant editor. Release it just above the @end when you see “Insert Outlet, Action, or Outlet Collection”. Fill in the popover.

Connection: Outlet
Object: Board View Controller
Name: button
Type: UIButton
Storage: Weak
Connect

The view controller now has a property named button that points to the button.

@property (weak, nonatomic) IBOutlet UIButton *button;

The TouchUpInside: method of the view controler has no need to use this property, since its sender argument is pointing to the same button. But we will use this property anyway, just to make sure that it points to the button.

- (IBAction) touchUpInside: (id) sender {
	NSLog(@"Button is pressed.  It belongs to class %@.",
		NSStringFromClass(self.button.class));

	[self.button setTitle: @"Veteran Button"
		forState: UIControlStateNormal];
}
Button is pressed.  It belongs to class UIRoundedRectButton.

Apple’s documentation

  1. Storyboarding (Single View Application)
  2. Converting to StoryBoards
  3. Your First iOS App
  4. Your Second iOS App: Storyboards

Things to try