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
- 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
- tippy app is up
- Notice few toggling of panels to have left hand and right hand panels on/off buy pressing this buttons.
- Next, click on Main.StoryBoard
- Click on the Big box inside of View Controller to select > click on the document icon (File Inspector) > Uncheck box ‘Use AutoLayout’
- Zoom in by double tapping
- Search Object library for ui label and drag into main app view: ‘uilabel’
- place the Label upper left hand side of the main app view
- Next, Search Objec (Obj) library (lib) for ‘uiview’ > Select ‘View’ element > Drag into Main view area.
- 3rd, element Search Obj Lib: ‘button’ and drag in to main app view.
- 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.
- 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.
- To see the options for simulators > click on active scheme button > you can see many versions of iPhones.
Note: if you have your iPhone
- 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.
- Or pick iphone 6s simulator > hit play button (Comamand + r)
- 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
- 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
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.
- Search ‘uiview’ > drag ‘View’ on to canvas
- Align the buttons as shown here and flatten view element to make a horizontal divider > add background color: grey
- Left align Bill, Tip, Total. Search ‘uitext’ > Drag ‘Text Field’. Right align second column. See below for update elements.
- Align all element to most right or left. Search segmented control (iOS version of radio button) > drag
- Make 3 radio buttons: Segments: 3
- Name buttons (18%, 20%, 25%), press return to save change each time.
- Command + R (play). Now we are done with designing our 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.
- image view/ text on top
- button (settings button gear looking thing)
- tab bar (bottom tool bar on many apps to toggle to different section of app)
- map view (displaying google map API)
- 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
- At this point, Command + R to Run the app.
- Add Title: Tip Calculator on Navigation bar
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)
- 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.
- 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.
- 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?
- 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.
User story: When click on Bill field, number keyboard is display.
- Select Bill text field > Text Input Traits > Keyboard Type > Decimal Pad
- Hit Play button to save and check if number keyboard is displaying.
User story: Calculate tip.
- Select Bill: Text field > Right click (double finger on MBP).
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
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.
- Ctrl + drag from Total value $0.00 to code. Name: totalLabel
- Add functionality to calculateTip function:
- Assign Tip: $10, Total: $110
- This accomplishes: calculateTip function can configure user views as change occurs on Bill field.
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.
- Run it, When typing input into Bill text field > Tip and Total values gets set to $10, $110 respectively.
Now, let’s dynamically change Tip and Total values.
- Ctrl + drag Bill Field to Code, Name: billField
- 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)”
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)
Once you run it, now we have too many decimal places.
- Fix this we specify how many decimal places we want to display: “$%.2f” (we want 2 decimal places)
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
- 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.
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.
- 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.