Getting Started - Part 2: Adding UIAlertViews (Popup Messages) to Your App

Getting Started Series by Nick Schneider.

 

Welcome to Part 2! You'll learn how to add UIAlertsView to your app. If you missed Part 1 then backtrack and download the Part 1 project.

Motivation

The current reading rate calculator workflow allows the user to enter values for the number of Words Per Line, number of Lines Read, and the time reading Time In Minutes. To make it more user friendly, we'll want to show a little more information about these values. If a user doesn't know how to calculate these values or what they mean, we'll need to help them out. The last thing we want is a frustrated user who stops using our apps. To make it easy, we'll use UIAlertViews (popups) to tell our users what these settings mean and how they work. We'll also use a new type of button!

Open Xcode and Get Started

Load your project and open up the Main.storyboard file. The first thing we are going to do is add buttons that will call our UIAlertView when tapped. Drag onto your view a Button. While it is selected, go over to the Attributes Editor and change the Type to Info Light. This will turn the large button into the common information button.

Place the button to the right of each Text Field, which you will have to resize. Remember our trick of holding down Option to click and drag a copy. Now that we placed our buttons, we'll connect them to code. Open up the Assistant Editor and hold Control while you click (or right-click) and draw the connection into the ViewController.h file. Each of the three will need their Connection to be an Action and given the names of wordsPerMinuteInfoButtonPressed, linesReadInfoButtonPressed, and timeInMinutesInfoButtonPress (Note: we use verbose names because it's easier to understand when we forget our code 6 months later).  We're also using "camel case" where the first letter is lowercase in the first word, and all other words have a capital first letter. Camel case is standard with writing Objective-C code and makes it easier for other developers to read your code.

 

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController
@property (weak, nonatomic) IBOutlet UITextField *wordsPerLineTextField;
@property (weak, nonatomic) IBOutlet UITextField *linesReadTextField;
@property (weak, nonatomic) IBOutlet UITextField *timeInMinutesTextField;

@property (weak, nonatomic) IBOutlet UILabel *wordsPerMinuteLabel;

- (IBAction)calculateButtonPressed:(id)sender;

- (IBAction)wordsPerLineInfoButtonPressed:(id)sender;
- (IBAction)linesReadInfoButtonPressed:(id)sender;
- (IBAction)timeInMinutesInfoButtonPressed:(id)sender;

@end

Implementing the UIAlertView

Now we can head on over to the ViewController.m file to add the functionality to call the UIAlertView. For better reusability we'll wrap the behavior for our alert messages in three new methods. We'll then add these method calls inside the IBAction's that we connected from Interface Builder. Add these three functions to ViewController.m,  above @end.

 

- (void) wordsPerLineInfoShowAlert {

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Words Per Line (WPL)"
message:@"To calculate WPL, count all words on 3 lines and divide by the number of lines. So if you count 45 words over 3 lines, your WPL will be 15."
delegate:self
cancelButtonTitle:@"Okay"
otherButtonTitles:nil];

[alert show];

}


- (void) linesReadInfoShowAlert {

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Lines Read"
message:@"Enter the number of lines read here. Remember to not count partial lines that consist of only a few words."
delegate:self
cancelButtonTitle:@"Okay"
otherButtonTitles: nil];

[alert show];
}


- (void) timeInMinutesInfoShowAlert {

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Time in Minutes"
message:@"Enter the number of minutes you spent reading here. It is acceptable to use decimals or round."
delegate:self
cancelButtonTitle:@"Okay"
otherButtonTitles: nil];

[alert show];

}

Here we are using the UIAlertView class to create our popups. We use the provided methods to initialize our view with a title, message, and a title for the button (i.e. Okay). We set the delegate to self, since the we want this file to get a message from when the alert button is pressed. 

Now all we need to do is call these from our IBAction methods that we previously linked. 

- (IBAction)wordsPerLineInfoButtonPressed:(id)sender {
[self wordsPerMinuteInfoShowAlert];
}

- (IBAction)linesReadInfoButtonPressed:(id)sender {
[self linesReadInfoShowAlert];
}

- (IBAction)timeInMinutesInfoButtonPressed:(id)sender {
[self timeInMinutesInfoShowAlert];
}

Build and Run your project and you now have UIAlertViews!

iOS Simulator Screen shot Nov 11, 2013, 9.31.47 PM.png
iOS Simulator Screen shot Nov 11, 2013, 9.31.51 PM.png
iOS Simulator Screen shot Nov 11, 2013, 9.31.55 PM.png

A little Bit Extra - Multiple Buttons

Say you wanted to have multiple buttons on your UIAlertView. We can do this in one of two ways, we can add then in the initialization of the object, or we can do it after. Adding the buttons after in convenient for conditional functionality, where you only want to give an option under certain conditions. We will show both ways of adding buttons here.

Initializing with Multiple Buttons

Initializing an UIAlertView with multiple buttons is straight forward. We need only to modify our argument to the otherButtonTitles method. Let's set up some buttons that will call the other UIAlertViews from our Words Per Line popup. Modify the wordsPerLineInfoShowAlert to have two more buttons:

 

 

 

 

- (void) wordsPerLineInfoShowAlert {

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Words Per Line (WPL)"
message:@"To calculate WPL, count all words on 3 lines and divide by the number of lines. So if you count 45 words over 3 lines, your WPL will be 15."
delegate:self
cancelButtonTitle:@"Okay"
otherButtonTitles:@"Lines Read",@"Time In Minutes", nil];

[alert show];

}

addButtonWithTitle Method

The alternative means to add buttons is to invoke the addButtonWithTitle method. Modify you lineReadInfoShowAlert and timeInMinutesInfoShowAlert functions to utilize this method and provide buttons calling the appropriate two alerts. You should get:

- (void) linesReadInfoShowAlert {

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Lines Read"
message:@"Enter the number of lines read here. Remember to not count partial lines that consist of only a few words."
delegate:self
cancelButtonTitle:@"Okay"
otherButtonTitles: nil];

[alert addButtonWithTitle:@"Words Per Line"];
[alert addButtonWithTitle:@"Time In Minutes"];

[alert show];
}


- (void) timeInMinutesInfoShowAlert {

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Time in Minutes"
message:@"Enter the number of minutes you spent reading here. It is acceptable to use decimals or round."
delegate:self
cancelButtonTitle:@"Okay"
otherButtonTitles: nil];

[alert addButtonWithTitle:@"Words Per Line"];
[alert addButtonWithTitle:@"Lines Read"];

[alert show];

}

Build and run and now all three alerts should have the right buttons!

iOS Simulator Screen shot Nov 11, 2013, 9.42.26 PM.png
iOS Simulator Screen shot Nov 11, 2013, 9.42.30 PM.png
iOS Simulator Screen shot Nov 11, 2013, 9.42.33 PM.png

Adding Functionality to the Buttons

Now we just need to make the buttons do something. Here we will take advantage of the buttons having titles, but you could also use the button index (the cancel index is alertView.cancelButtonIndex), then each additional button is a larger positive integer (1, 2, etc.).

When we press a button, we will check the title and then call the Info method for the appropriate button. We're using the methods that we wrote earlier, which means we're using the same code in two places!

- (void)alertView: (UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{

NSString *title = [alertView buttonTitleAtIndex:buttonIndex];
if([title isEqualToString:@"Words Per Line"]) {
[self wordsPerLineInfoShowAlert];
} else if ([title isEqualToString:@"Lines Read"]) {
[self linesReadInfoShowAlert];
} else if ( [title isEqualToString:@"Time In Minutes"]){
[self timeInMinutesInfoShowAlert];
}

}

Whenever we press a button in a UIAlertView, this function will be called. We check the title of the button and then decide wether or not to call another function. We allow the Okay button to dismiss the alert as before. Build and Run and see it in action!

You Added UIAlerts to Your App! What's Next?

Thank you for following our walk-through! We hope you found it helpful.

In Part 3 we will continue with our Read Rates app and implement the stop watch.

Download the Project from Today

Share with us your struggles, successes, and stories below! 

Nicholas M Schneider

Nicholas M Schneider is a 2010 graduate from the Kate Gleason College of Engineering who is now a Doctoral Candidate at the University of Pennsylvania. Originally from an obscure town south of Buffalo, New York, he attended the Rochester Institute of Technology where he received concurrent Bachelor of Science and Master of Science degrees. While there he had a number of Co-ops including a six month stay as a Design Engineer at Lockheed Martin and Research positions with Dr. Satish Kandlikar. Nicholas currently works with Dr. Haim H Bau in the field dubbed “in situ electron microscopy of liquid systems” where he studies applications in energy and biological systems. Outside of the lab, Nicholas Schneider is a Graduate Associate in Rodin College House and enjoys running (he ran his second Philly Marathon this past November), cooking, baking, reading, and justifying his coffee addiction by making it a hobby.