Learn to Code iOS Apps 3: Your First App

In this tutorial, you will create a simple iOS game where you have to tap a button as many times as you can in 30 seconds. Just don’t get too excited and smash your screen by mistake! By Mike Jaoudi.

Leave a rating/review
Save for later
Share
You are currently viewing page 4 of 5 of this article. Click here to view the first page.

Time For a Timer

Now that game works and keeps score, you’ll need to set up the timer to count down from 30 seconds to zero, when the player’s turn will end.

First, set up a method that will initialize the game state. Add this method to ViewController.m:

- (void)setupGame {
    // 1
    seconds = 30;
    count = 0;
    
    // 2
    timerLabel.text = [NSString stringWithFormat:@"Time: %i", seconds];
    scoreLabel.text = [NSString stringWithFormat:@"Score\n%i", count];
    
    // 3
    timer = [NSTimer scheduledTimerWithTimeInterval:1.0f
                                             target:self
                                           selector:@selector(subtractTime)
                                           userInfo:nil
                                            repeats:YES];
}

Part 1 of the method resets the clock to 30 seconds and the tap count to 0. This will be the initial state for the game.

Part 2 of the method resets the on screen display. The stringWithFormat call and the %i should already be familiar to you!

Part 3 is one dense-looking bit of code. Here, you’re setting up a NSTimer object that will send you a message every second. That way, you’ll be able to update the number of seconds remaining and end the game after 30 seconds.

If you break down the various parts of the NSTimer call, it isn’t too scary:

  • Time Interval is simply how often you want the timer to go off (1 second, in this case)
  • Target is which instance to send a message to every second. You’re in the view controller now and you want the message to go to the view controller, so the target is self.
  • Selector is what method you want to call. It isn’t enough to write the method, you also need to put @selector around the method name.
  • User Info is any extra info you want stored with the timer. You won’t need anything for this timer so you say nil to represent nothing.
  • Repeats says if the timer should repeat or just fire off once. You want the timer to go off every second until you say stop, so this is set to YES.

You’ve asked the timer to call the subtractTime method every second but you haven’t defined it yet! :]

Add the following code to ViewController.m:

- (void)subtractTime {
    // 1
    seconds--;
    timerLabel.text = [NSString stringWithFormat:@"Time: %i",seconds];
    
    // 2
    if (seconds == 0) {
        [timer invalidate];
    }
}

Part 1 of the method should be familiar looking. Here, you’re decreasing the number of seconds and then updating the label on screen with the new time.

When the number of seconds hits 0, you’ll want the timer to stop and end the game. When you tell the timer to invalidate, it will stop the timer from calling subtractTime again.

There’s just a few last-minute things to add to your app until it’s done! :]

Starts and Stops

Lots of pieces are now in place! To keep things simple, you can just start the game, and the timer, when the app launches. Update the viewDidLoad method in ViewController.m:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [self setupGame];
}

Remember, iOS will call viewDidLoad automatically for you when the storyboard and view are loaded. The call to the setupGame method you just wrote will then start things off.

Launch the app and see what kind of high score you can reach!

Game Over Weirdness

Did you notice a few odd things about how your app handles the end-of-game scenario? :]

When the timer hits zero, you can still tap the “Tap Me” button, so you’ll need some way to prevent the user from clicking it! As well, there’s no way to restart the game and try again. Hmm, that could be a problem! :]

An alert sounds like a good fit here. When the game is over, you can add an alert that will pop up showing the score and displaying a button to the user that that lets you play the game again. Since you want the alert to show when the game is over, add the code for it inside the subtractTime method:

    // 2
    if (seconds == 0) {
        [timer invalidate];

        // new code is here!
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Time is up!"
            message:[NSString stringWithFormat:@"You scored %i points", count] 
            delegate:self
            cancelButtonTitle:@"Play Again"
            otherButtonTitles:nil];

        [alert show];
    }

A UIAlertView has a title, message, and one or more buttons. The first part of the new code sets up the alert, and then sending it the show message will display it to the user.

Break down the various pieces of the alert call, and you’ll see the following:

  • Title – the title that will appear at the top of the alert.
  • Message – the message in the center of the alert. In this alert, you want to display the score.
  • Delegate will be set to self, just like the timer. Delegates will be explained in the next section.
  • Cancel Button Title – the title of the button. For this app, it is Play Again.
  • Other Button Titles – a list of button titles. You only need a play again button so set this to nil.

Now, build and run the project and see how your new, end-game code works! :]

Awesome! So the alert now pops up and shows the high score. And pressing “play again”…uh, doesn’t do anything! What gives?

In your Storyboards, you connected an IBAction to the button to handle the tap events, but there’s nothing like that for alert buttons. Instead, you need to use something called a delegate.

Dealing With Delegates

A delegate is a way for an object to find out about interesting things that are happening. For example, you might set your alarm clock to wake you up at 7 in the morning or you might ask your friend to call you when she gets home. In these examples, you are the delegate (the thing being told) and the alarm clock and your friend are the things that will tell you something (such as, “it is time to wake up” or “I am now at home”).

Going back to the app, your alert has something interesting to tell – when the “Play Again” button is pressed. Your view controller would love to know when that happens, so it should become the alert’s delegate.

So you need to state that the View Controller is a delegate for UIAlertView. Near the top of ViewController.h, change the line starting with “@interface” like this:

@interface ViewController : UIViewController<UIAlertViewDelegate> {

Just as the alarm clock has a certain signal it can send (playing music or an alarm sound), UIAlertView has a set of messages it can send to its delegate. You can check out the documentation for a full list, but the one you’re concerned with here is called “alertView:clickedButtonAtIndex:”. This will send a message when a button is clicked.

Now you just have to put that method into the View Controller!

Add the code below to ViewController.m:

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    [self setupGame];
}

To summarize: when the game ends, a UIAlertView will be displayed with the score and a button. When the button is tapped, a message will be sent to the delegate — your view controller — which will then call the setupGame method you wrote a while back. To refresh your memory, setupGame resets the time and score and restarts the game.

What are you waiting for? Build and run your app and test your skills in a button tapping frenzy!

Congratulations!! You have now made your first iOS app – be sure to show it off to your family and friends! :]

Mike Jaoudi

Contributors

Mike Jaoudi

Author

Over 300 content creators. Join our team.