Coding Workshop 3 - How Much App Part 2

homepage

There are 4 actions that we need to code.

addDigit Function

Each time we tap on one of the number buttons we need to append it or add it to the end of our total string.

However, it is currently set for 0 so we will need to do a conditional check first and if it is 0 we will just replace 0 with the number tapped, otherwise we will add to our total by appending the number to the end.

 

  1. Inside our parent struct view, create a function called addDigit that will receive a number as a String

Note: By using an _ as the beginning of our parameter, it means that when we call the function we can simply pass in the string without specifying the argument name. i.e. addNumber("7") instead of addNumber(number: "7")

  1. We can create a condition using an if...else clause and then in the case that the comparison of the number to 0 is true, we assign number to the total, lease we assign to total the previous total plus the number. Since number and total are both strings, the appended string just gets added after the existing string so "7" + "8" - "78"

  1. This can be simplified using a ternary operator newValue = WTF (What ? True : False)

  1. Then we can add this function then as the action for our numberButton button's action, passing in the number that we get as the function argument.

Text View line limit

If we test, we see it works, but if you go beyond 6 digits we are on to two lines, not good.

We can set the line limit on our Text view to 1

This limits the line, but it also truncates the number. Not good.

MinimumScaleFactor

To accommodate this we do what the iPhone Calculator app does, it reduces the text size using a minimumScaleFactor of our choosing

Now the bill will have to be awfully large before it truncates.

Dealing with the decimal

Right now there are two issues with the decimal.

  1. We can add more than 2 digits after the decimal.

  2. We can add a second decimal point and this makes no sense.

Computed Properties

To handle this, we can create 2 computed properties that will return a Boolean value (true or false) that we can use to determine if we can add more digits or a decimal point.

canAddDecimal

  1. Create a computed property called canAddDecimal that is a Bool type

This means we need to provide a check that will be either true or false. What we want to do is to count the number of decimal points our total already has and if the count is 0 we will return true, otherwise, return false

We can use a filter function on a string because a String is essentially an array of characters so if we filter and look only for "." we will get an array of only "." and then we can count them.

These 4 lines can be simplified to a single line that returns the truthfulness of comparing the count of the filter to 0. It will be either true or false

And, since there is only one line in the body of our computation, we can omit the word return

For a video on filtering and other higher order functions, see:

https://youtu.be/9wAhKodOyFI

canAddDigit

  1. We need a similar function for canAddDigit

Again, we start with a variable called canAddDigit that is a computed variable that is a Bool type

We need to be able to compute the index of the decimal point and find out what that distance is from the start and then subtract it from the total to see that we have no more than 2.

  1. First we can use a guard check to see if the decimal index even exists. If it doesn't we return true.

  2. If it does we can calculate the index a the distance from the start to the found index.

  3. hen we can return that count truthfulness if it is less than 2

How did I figure this computation out? I GOOGLED it.

With these to properties now available I can make some changes to my addDigitFunction

  1. first, we check to see if we can actually add a digit, because if we already have a decimal and 2 digits, we can't

  1. then we check to see if what we have tapped is a decimal and if so, we can see if we are allowed to add it and if so, we add it onto the total .

Note: total += number is the same as total = total + number

  1. if it is not a decimal. We use what we already had in place

BackSpace Button action

We still have to code the action for the backspace button

  1. For this, we check first to see how many digits we have already in our total by using the count

  2. if it is equal to 1 digit, when we backspace we will set it back to the string "0"

  3. otherwise we simply remove the last digit

Clear Button

For the clear button, it is going to be quite simple,

We can simply set the total back to "0" and leave the numPeople and tipPct the same.

Calculate Button

The calculate button is not going to actually do any calculations. Instead it is going to present a second view that will handle the calculations and display them to the user. The presentation of that view is going to be done by way of a Modal Sheet that pops up part way from the bottom of the screen.

In order to do that, the calculate button is going to toggle that action by simply setting a state variable to true.

  1. This means we need to create another state property on our view that will be initialized as false.

  1. Then when someone taps on the button it will be set to true.

One More thing.

There is one more thing, if our total is 0 then there is nothing to clear or calculate. So we can disable both of those buttons if that is the case. We can apply a .disabled(Bool) modifier to the HStack containing both of those buttons and that will then get applied to those buttons. The argument for the disabled modifier is a Boolean and it will be true whenever total == "0" or "0."

We can convert the total which is a string representing a number using Double(total) and compare it to the number 0

Back to Project Index