iOS app: tip 💁🏻‍ calculator

Heggy Castaneda
12 min readMar 14, 2018

--

Goal: Build tip calculator iOS app that calculates different tip amount dynamically.

Code: Check out my Code repo for complete code. 👩🏻‍💻

Take away: I had to think hard 🧐 on how to dynamically update app to calculate right tip amount when user tap on different tip button. The major break through is connecting tip buttons. In iOS buttons are segmented arrays and each button can be represented as index of array. Once I realized that 🦉then it was really matter of creating my tip [18%, 20%, 25%] array which mapped to corresponding index of button segment. Ex) segmented button index 0 maps to my tip array 18%. (Zero based index)

Lastly, linking view to function or variable inside of Swift was magical 😍 moment to me. 😮 I ❤️ how iOS app coding is very visual like I am coding inside of debugger. Go Swift! 👩🏻‍💻

  • Let’s open Xcode. File > New > Project > Single View App
File> New Project
  • Product Name: tippy
  • Team: this is your team name that is registered with Xcode on your macBook
  • Organization name: Leave it default
  • Organization Identifier: It is your website name but reverse DNS order.
  • Press Next > save it on your desktop > Create
Name your project
  • tippy app is up
  • Notice few toggling of panels to have left hand and right hand panels on/off buy pressing this buttons.
Toggle Panels by clicking on it
  • Next, click on Main.StoryBoard
Main.StoryBoard
  • Click on the Big box inside of View Controller to select > click on the document icon (File Inspector) > Uncheck box ‘Use AutoLayout’
Disable AutoLayout
Disable Trait Var
  • Zoom in by double tapping
Zoom by double tapping
  • Search Object library for ui label and drag into main app view: ‘uilabel’
uilabel found
Drag in Label inside of main rectangle app area
  • place the Label upper left hand side of the main app view
UILabel is up
  • Next, Search Objec (Obj) library (lib) for ‘uiview’ > Select ‘View’ element > Drag into Main view area.
drag View
View is up now
  • 3rd, element Search Obj Lib: ‘button’ and drag in to main app view.
Drag Button into main view
Button element up
  • Look to your left side panel, check out the listing of all the elements you’ve added. This is similar to layers view in photo shop.
Layers’ View or Document outline consists of Label, View, Button elements we added
  • Next, click on upper right hand corner of panel > select ‘properties’ icon
  • Try changing background color of ‘view’ icon: Click on ‘view’ > make sure Property icon is highlighted in blue > change background color to light grey.
pick view’s background color
  • To see the options for simulators > click on active scheme button > you can see many versions of iPhones.

Note: if you have your iPhone

simulator size
Different iPhones
Once plug in my iphone to mac book > I can see my iphone device
  • Comamand + r (or hit the play button) to run simulator. I have my device connected so I will now see it running on my iphone.
running on my iPhone
  • Or pick iphone 6s simulator > hit play button (Comamand + r)
iPhone 6s simulator up
  • iOS app) it is ok to have absolute position. What you see it what you get. Move Label to the left on the stortyboard > hit play button (command + r). Notice the change is reflected on your simulator.
  • Let’s nest element Label inside of view element (creating hierarchy of parent > child relationship)
  • Drag ‘label’ inside of ‘view’ element
Nesting label element inside of view element
Notice hierarchy has changed Label is nested under View
  • Hover over view > see the mouse icon change to hand icon > grab view and notice Label and View moves together since they are grouped together (nested).

Note: Why do we group? Use case1: Hide/Fade-in all elements that are grouped together. Use case2: Insert animation all elements grouped together get the special effect.

Note: Reason absolute position is encouraged in iOS development (where in HTML, it is a major violation) is once we apply auto layout on top of absolute positioning then auto layout helps the app to be responsive (stretch this element or make it landscape as iphone behavior requires)

  • Hit Play to view the updated app.
  • Time for real building to start. Delete all the elements.
  • Search ‘uilab’ > drag 4 labels into the canvas ui
deleted all elements and searched ‘uilab’ > drag labels four times

Note: Quickly copy elements on canvas: drag one Label on canvas > click on Label element > option + drag (on the canvas) which quickly copy elements. This way we don’t have to drag 4 different times from obj lib to canvas.

option + drag to quickly copy elements
  • Search ‘uiview’ > drag ‘View’ on to canvas
uiview View element added
  • Align the buttons as shown here and flatten view element to make a horizontal divider > add background color: grey
buttons aligned to look nice and horizontal divider with grey background color
  • Left align Bill, Tip, Total. Search ‘uitext’ > Drag ‘Text Field’. Right align second column. See below for update elements.
right align second column
  • Align all element to most right or left. Search segmented control (iOS version of radio button) > drag
segmented control last element to add
  • Make 3 radio buttons: Segments: 3
  • Name buttons (18%, 20%, 25%), press return to save change each time.
Radio button (segmented control iOS name)
rename buttons and hit return
  • Command + R (play). Now we are done with designing our app.
iphone App

Note: https://pttrns.com/iphone-patterns This site has many iOS app and we can generalize that most iOS app use 4 -5 commonly used object library view elements.

  1. image view/ text on top
  2. button (settings button gear looking thing)
  3. tab bar (bottom tool bar on many apps to toggle to different section of app)
  4. map view (displaying google map API)
  5. ui web view (displaying portion of web page)

There are very small number of controls that we end up using in iOS app. No need to get overwhelmed by object library.

Master view layouts means master above view types (image, button, tab bar, map, ui web) really well and corresponding properties (configuration and setting their behaviors).

  • Important: under object lib: Navigation Bar. Never NEVER manually drag it into your canvas.
  • How to add navigation bar RIGHT way: Editor > Embed in > Navigation Controller
Navigation Controller to Embed in Navigation Bar
Navigation Bar is on
  • At this point, Command + R to Run the app.
  • Add Title: Tip Calculator on Navigation bar
Title our app
hit play to see your changes reflected on your app

This is ends the designing the view layout.

  • Add functionality to the app
  • Check if keyboard is connected to the app. Click on simulator iPhone > Bill text box area > Hardware > Keyboard > Connect hardware keyboard (if you don’t see keyboard on your simulator: command + k to bring up the keyboard). This is called Toggle keyboard (command + k)
  • Dismiss the keyboard view: Add obj lib: ‘tap gesture recognizer’ > drag onto the main part (bigger white space of your app (main view), careful not to put it under any special buttons)
Tap Gesture Recognizer
  • Now we have gesture recognizer set on main view, let’s add some dynamic behavior (functional). With Tap Gesture Recognizer selected on left panel (highlighted in blue) > click on top right side double ring icon.
Very top Double Ring icon to show Swift code
side by side view on right side with swift code on right side
  • Control +drag tap gesture recognizer into the code block within the class ViewController code block. Notice it is right before last curly ( ‘}’ )of the class function.
Drag tap gesture recog > code block
onTap function is now created
highlight Tap Gesture > double tap to confirm Action set on it
  • Try it out. Build by hit play button > tap main part of the app (big white blank background of app). Do you see hello in debugger console?
  • Code: Hide the keyboard `view.endEditing(true)`
  • Hit play and try it out on your simulator. Does keyboard hide?
hide keyboard
Toggle keyboard
  • Click on Bill: Notice that for Bill, we want number keyboard to show up.

Look around what text field properties there are. Note: Secure Text Entry for password.

Learn text field property

User story: When click on Bill field, number keyboard is display.

  • Select Bill text field > Text Input Traits > Keyboard Type > Decimal Pad
Decimal Pad keyboard to pop up
  • Hit Play button to save and check if number keyboard is displaying.
decimal pad displays

User story: Calculate tip.

  • Select Bill: Text field > Right click (double finger on MBP).
Notice Sent Events

Note: ‘Sent Events’ section lists all the events that can happen in text field. Ex) If my finger touch down > fire some action. If Touch up inside > Do something.

User story: Every time user changes the Bill: text field, update the tip value.

  • Drag Editing changed into code > Name: calculateTip
link editing changed action to Code which will calculate Tip
Editing Changed calls calculateTip

User story: calculateTip function dynamically updates Total and Tip values.

  • Ctrl + drag from Tip value $0.00 to code. Whenever we want to modify something, we drag that field and connect to the code field.
  • Name: tipLabel (Notice the naming convention. First part of name: tip is description what it does. 2nd part of name: Label is type.
Set val to code
  • Ctrl + drag from Total value $0.00 to code. Name: totalLabel
Connect > Name is totalLabel
Connect from left panel List to code also.
  • Add functionality to calculateTip function:
  • Assign Tip: $10, Total: $110
  • This accomplishes: calculateTip function can configure user views as change occurs on Bill field.
Assign static values to tipLabel and totalLabel ($10, $110)

Notice: As you type you can see other functions we can add to tipLabel. We can change background color tipLabel.textColor. We can align text as we saw under properties.

Other things we can do to tipLabel
  • Run it, When typing input into Bill text field > Tip and Total values gets set to $10, $110 respectively.
Tip Total number gets assigned when Bill value is changed

Now, let’s dynamically change Tip and Total values.

  • Ctrl + drag Bill Field to Code, Name: billField
Naming Outlet billField
billField now connect from view
  • calculateTip function:

// Double ( string ) > converts string into number ex) billField.text is string.

// Notice ! > Swift really likes !

// ?? > otherwise. If Double(billField.text!) is not valid (ex: If user inputs ‘abc’ inside of Bill field > Swift won’t be able to convert ‘abc’ into number > Therefore set default value 0.

let bill = Double(billField.text!) ?? 0

// \( *Whatever inside here will be treated as variable* )

tipLable.text = “$\(tip)”

20% tip

User story: Number format should be currency (two zeros after decimal point) format.

// $“%f”, tip replaces %f and following tip is processed as variable (%f for decimal values)

// “%@” > strings | other objects

// “%d” > extra values

tipLabel.text = String(format: “$%f”, tip)

format to show decimal points

Once you run it, now we have too many decimal places.

really long trailing decimal places
  • Fix this we specify how many decimal places we want to display: “$%.2f” (we want 2 decimal places)
format 2 decimal places “$%.2f”

User story: When user tabs 18%, 20%, 25%; tip amount should reflect corresponding tip.

  • ctrl + drag from Tip buttons (segmented tabs) to code. Name: tipControl
tipControl
  • Incorporate tipControl’s segmented Index which each tab corresponds to array index 0, 1, 2
  • Run to test tip calculating correctly. It is reading the tip val correctly but tab toggling doesn’t trigger new updated value to show up.
Select the UISegmentedControl! tipControl variable
tipPercentages[tipControl.seletedSegmentIndex] will retrieve assigned value of array
tip is calculating for right segment
Bug found: When toggle to different tip amount tab > amount doesn’t get updated

User story: As tip tab changes as tip and total value should dynamically update.

Notice that when toggling to different tip amount tab, the tip and Total is not triggering calculateTip function.

  • Go to tip segmented buttons > right click > value changed > Ctrl + Drag value changed on top of calculateTip function.
  • Once done right click on tip segmented to see the assignment on value changed.
  • Anytime user tabs on any part of tip buttons > calculateTip function will execute to provide newly updated value.
Ctrl + Drag Value Changed to calculateTip function
Right click on tip button to see the value changed linked to calculateTip function
  • Hit Play button to run the simulator. Tip and Total values are dynamically calculates corresponding tip amount as user clicks on 18%, 20%, 25% tip buttons.

Thank you CodePath and SwiftGuy for tutorials to make my tip calculator post possible.

--

--