The Swift Swift Tutorial:A Swift Pizza App with UI

[Updated to Swift 2.0 8/30/15]
I thought I’d do some writing for the advanced beginner to intermediate level programmer. That’s a loose definition, but I’ll define it as someone who can find their way around Xcode well enough that I can say “open a single view template and add two buttons and a label” and can do that without help. In this session, we’ll go through variables and constants and set up a simple application.

Opening a Swift Template

Open a new single view template named PizzaDemo. After selecting a single view project, you will the language field.

2015-08-30_10-15-23

Change that to Swift,  Add the Name PizzaDemo to the product name. Save the project. Bring up story board. We’ll do this quickly, not using auto layout in this demo. To hel pus keep in the correct dimentions, we’ll set the size class  to a iPhone. select the wAny hAny onthe bottm of the storyboard. Drag the cursor in the popup that appears to Compact Width, making a rectangle like this:

2015-08-30_10-33-39

Once you made the rectangle, click on it. you will have a storyboard that isn’t square but more iPhone looking.  Add a label at the top at 32 point centered with the words Pizza Computer, two buttons below them and the second label and the slider something like this:

Layout for the pizza app
Layout for the pizza app

Open the assistant editor and change automatic to preview to help align things properly.

2015-08-30_10-43-33

You may find in the preview that some elements don’t fit right or are off the screen.

2015-08-30_10-45-09

Move then around until they do.  After laying everything out, set the assistant editor back to Automatic to display the ViewController.Swift file .

Wire up the controls to the view controller using control-drag. If you are used to Objective-C,  you will immediately find out there is no header files in Swift. Drag both objects and actions directly into the view controller file.  As you drag, drag them below the class declaration like this:

2015-08-30_10-47-43

 

Drg from the Pizza Computer label and make an outlet called resultsDisplayLabel. Control-drag from the 0.00 label and make a outlet named sliderDisplayLabel.  Control-drag from the slider and make a outlet named diameterslider.  Control-drag  from Compute button and make an action named computeButton.  Control-drag from the Clear button and make an outlet name clearDisplayButton. Finally, make an action for our slider named diameterSlider.

As you control-click and drag the controls to the view controller, you will notice Xcode acts slightly differently than it does with Objective-C. The two labels will of course default to an @IBOutlet. The button and slider do not default to a @IBAction, but instead an outlet. Be sure to change them correctly to actions. This makes sense since you might need both an outlet and an action for some controls, like our slider.

When done you should have the following outlets and actions.

class ViewController: UIViewController {

    @IBOutlet var resultsDisplayLabel : UILabel!
    @IBOutlet var sliderDisplayLabel : UILabel!
    @IBOutlet var diameterSlider : UISlider!
    @IBAction func computeButton(sender : UIButton) {
    }
    @IBAction func clearDisplayButton(sender : UIButton) {
    }

    @IBAction func diameterSlider(sender : UISlider) {
    }

Adding Variables and Constants

Close the assitant editor.  Go to the ViewController.swift File.  Above the @IBOutlet declarations and below the class declaration, let’s add the following:

    let π=3.1415926
    let pi=3.1415926
    let clearString = "I Like Pizza!"
    let maxPizza = 24.0
    var z = 5.0
    var 🍕 = 0.0
    var diameter = 10.0
    var intArea = 0
    var area:Double = 0.0

The let keyword sets the identifier to a constant. The var identifier sets the identifier to a variable. Identifier names can use the entire Unicode character sets. Emoji and non-roman character sets are legal in variable and constant names.

Swift requires variables and constants to be initialized to a value when created. You cannot do this:

var diameter  //will cause a fatal compiler error

One reason for the compiler’s crankiness is in the line.

var area:Double = 0.0

Only in line 8 do I declare a type, whihc in this case is Double. You can declare types explicitly, but Swift often uses implicit typing. It decides on the type based on the what gets assigned to it. For example

var intArea = 0

will be a Int and

var diameter = 10.0

a Double due to the inclusion or exclusion of a decimal point.

let clearString = "I Like Pizza!"

will be a string due to the quote marks. Swift must have something assigned to figure out a type. The lack of little yellow warning triangles is the other reason. While some people have laughed at Apple’s contention that many common errors simply cannot happen, it’s very, very difficult to leave a loose undeclared variable in Swift, though you might have an unused property or two after this point with no compiler complaints.

Using Properties and Methods

Change viewDidLoad() to the following:

override func viewDidLoad() {
        super.viewDidLoad()
        resultsDisplayLabel.text = clearString
        view.backgroundColor = UIColor(red:0.99,green:0.9,blue:0.9,alpha:1.0)
        diameterSlider.value = 0.0
    }

Unlike Objective-C, Self is missing from this code. Unless there is a case where the compiler can get confused, Swift assumes the properties are self. Properties use the dot notation most developers are familiar with. To set the text property of our label to the value of our constant clearString  we use resultsDisplayLabel.text = clearString. We set our diameter slider to 0 with this line:

diameterSlider.value = 0.0

Line 4 shows a Swift’s method equivalent of [UIColor colorWithRed:green:blue:alpha:] In objective-C. We will cover functions next time, but the parameters in Swift can be named, and this makes for a much simpler constructor instead of the bulky class method. In general, the [Class typeWithParameter1:a Parmeter2:b] format of Objective-C methods loses the typeWith and gets rearranged to Class(parameter1:a,parameter2:b) in Swift.

Now change the @IBAction methods to this:

   @IBAction func computeButton(sender : UIButton) {
        area = pi * z * z
        let formattedAnswer = String(format:"%6.2f",area)
        let unitsString = "  square in of 🍕"
        resultsDisplayLabel.text = formattedAnswer + unitsString
    }
    @IBAction func clearDisplayButton(sender : UIButton) {
        resultsDisplayLabel.text = clearString
        diameterSlider.value = 0
    }

    @IBAction func diameterSlider(sender : UISlider) {
        diameter = Double(sender.value) * maxPizza
        z = diameter / 2.0
        let feedbackString = String(format:"%6.2f in",diameter)
        sliderDisplayLabel.text = feedbackString
    }

Line 15 above

let feedbackString = String(format:"%6.2f in",diameter)

uses another example of a well-used method in its new form. You can use \() in strings to get values into strings, \() is meant for debugging only. Swift’s String type has a formatter NSString(format:"%6.2f in",diameter)

Line 13 has an explicit cast to Double.

diameter = Double(sender.value) * maxPizza

Swift is very strongly typed. In this case, sender.value returns a Float not a Double. Even though both are real numbers, Swift won’t let you assign or do math with one to the other. Make sure you know the types you are working with. Cast a property to the type you want or declare the variable as the type returned.

Build and run the app:

What's the area of a 12" pizza?
What’s the area of a 12″ pizza?

We can now calculate how much area we have for toppings on a pizza. We quickly went through declaring constants and variables, Assigning values to properties and using the factory methods we know and love in Objective C. We’ve also seen how Swift enforces strong typing. Next time we’ll look at basic structs, functions, classes and overrides as we build a more robust model for our pizza app.

The Whole Code

Here is the complete view controller code.

//
//  ViewController.swift
//  PizzaDemo
//
//  Created by Steven Lipton on 6/8/14.
//  Revised by Steven Lipton on 8/30/15 for Swift 2.0.
//  Copyright © 2015 MakeAppPie.Com. All rights reserved.
//

import UIKit

class ViewController: UIViewController {

    let π=3.1415926
    let pi=3.1415926
    let clearString = "I Like Pizza!"
    let maxPizza = 24.0
    var z = 5.0
    var 🍕 = 0.0
    var diameter = 10.0
    var intArea = 0
    var area:Double = 0.0
    
    @IBOutlet var resultsDisplayLabel : UILabel!
    @IBOutlet var sliderDisplayLabel : UILabel!
    @IBOutlet var diameterSlider : UISlider!
    @IBAction func computeButton(sender : UIButton) {
        area = pi * z * z
        let formattedAnswer = String(format:"%6.2f",area)
        let unitsString = "  square in of 🍕"
        resultsDisplayLabel.text = formattedAnswer + unitsString
    }
    @IBAction func clearDisplayButton(sender : UIButton) {
        resultsDisplayLabel.text = clearString
        diameterSlider.value = 0
    }
    
    @IBAction func diameterSlider(sender : UISlider) {
        diameter = Double(sender.value) * maxPizza
        z = diameter / 2.0
        let feedbackString = String(format:"%6.2f in",diameter)
        sliderDisplayLabel.text = feedbackString
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        resultsDisplayLabel.text = clearString
        view.backgroundColor = UIColor(red:0.99,green:0.9,blue:0.9,alpha:1.0)
        diameterSlider.value = 0.0
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}



8 thoughts on “The Swift Swift Tutorial:A Swift Pizza App with UI”

  1. I seem to get an error as follows: 2014-06-16 22:48:58.040 Pizza App[51676:2627590] -[_TtC9Pizza_App14ViewController diameterSlider:]: unrecognized selector sent to instance 0xb82b600
    2014-06-16 22:48:58.058 Pizza App[51676:2627590] *** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘-[_TtC9Pizza_App14ViewController diameterSlider:]: unrecognized selector sent to instance 0xb82b600’. I’ve tried to fix it, with no luck.

    1. I have some theories. One thing you might look into is if you changed the name of diameterSlider at any time in code from what got entered when you connected from the storyboard to your view controller. It’s something I’ve seen since I started back with ios4 that the XML buried deep within the code identifying the outlets doesn’t update when you change the name of a method connected to the outlet.

      Like I said earlier today, We are going to replace the slider with some buttons tomorrow, and that should confirm or shoot down my suspicions.

      1. Thanks Steven for the quick responses. I went through the tutorial again and it worked. Not sure what I did different. Had a problem with the iPhone simulator previewing incorrectly, but I figured out the constraining feature. Cheers.

  2. Hi Steven, under “Adding Variables and Constants” the “let maxPizza = 24.0” is missing, i saw it later under the “The Whole Code” section, but when xcode shows a compiler error, it is at the beginning a bit confusing for someone who is chronologically reading/programming with this post.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s