Week 1 of Learning SwiftUI

Using 100 days of SwiftUI.

Posted by Joe Speakman on January 20, 2021 · 10 min read



Hey! In my last post, I mentioned that I am starting the 100 Days of SwiftUI this is a great way to learn SwiftUI. HackingWithSwift.org

Day 1... (err day 16?)

The first 15 days are used to teach you the Swift basics that every SwiftUI developer needs. Because I felt comfortable with my experience of developing multiple Swift/ UIKit projects, the program allows you to skip the first 15 days. The first project is an app called WeSplit, a simple tip calculator that calculates each person’s amount. Also introducing how Form, NavigationView, and @State work in SwiftUI.

The Form is the SwiftUI version of UIKit’s UITableView, with no need to manage pesky cells. However, SwiftUI Has a limit where it can only display ten objects within the struct. Additionally, I learned today that in SwiftUI, there is no need for NavigationViewControllers 🎉. SwiftUI Handles all of the Navigation between views for you!

The @State allows you to set a program state that can be modified within the view. To call on this @State, you would add a $ to the call to tell SwiftUI That you want to update the interface based on changes to this item. In an instance of a Text object (label for my UIKit friends), you would not need a $ as the Text has no way of changing the data of the string that is displayed.

My final take away from today is how this project is using ForEach. It allows you to loop through each object and run a closure once for every item. This will enable you to get around the previously mentioned limit of data in SwiftUI.

Day 2 (Day 17)

Today I continued learning how Form,@State, and Picker are used in SwiftUI. The first task for today is to read data from a TextField, to do that we must add:

@State private var checkAmount = ""

Before the View struct. Then by adding this code into the view body making sure to add $ to allow the two-way binding.

var body: some View {
    Form {
        Section {
            TextField("Amount", text: $checkAmount)
        }
    }
}

By using the $checkAmount, it tells SwiftUI to update and refresh the view every time there is an edit to the contention the TextField.

The next step is to add a Picker which allows users a way of selecting the number of people that are splitting the bill. This can be achieved by using a ForEach with a data set of 2-100. Similar to before, a @State object is needed to be able to update the view. Then we add in mathematical logic to create the totalPerson variable:

var totalPerPerson: Double {
    let peopleCount = Double(numberOfPeople + 2)
    let tipSelection = Double(tipPercentages[tipPercentage])
    let orderAmount = Double(checkAmount) ?? 0

    let tipValue = orderAmount / 100 * tipSelection
    let grandTotal = orderAmount + tipValue
    let amountPerPerson = grandTotal / peopleCount

    return amountPerPerson
}

This variable will return the value of the amount of the total plus tip, divided by the number of people.

The finish line is in sight for this project! The final thing to solve for is the last TextField that shows the total amount that each person owes. When displaying the output, it will add more than the standard hundredths decimal value. This can be resolved using the printf formatting to limit the decimal spaces.

Section(header: Text("Total amount")) {
                    Text("$\(checkTotal, specifier: "%.2f")")
                }

By using "%.2f" we can use string interpolation to modify what is being displayed. This type of string interpretation dates back to the C days and can be fairly complex. Read more about Printf Formatting Here. That is a Wrap for today. This has been an enjoyable project, and I cannot wait to see the next project!

Day 3 (Day 18)

Today is the final day of WeSplit. I feel excellent, and the project has been a joy to work on. I am learning some good fundamentals for SwiftUI. Additionally, I did the WeSplit review, which was a total of 12 questions, and I scored a very respectable 83%! I feel comfortable enough with my knowledge to accept the challenge of my first challenge day tomorrow. However, before I move on to the next project, there are three challenges to take the project further:

  • Add a Header to the third section
  • Add another section showing the total amount for the check (original amount plus the tax) before the split.
  • Change the “Number of people” picker to be a text field, with the correct keyboard

The first challenge is simply adding the header to the total amount section with the following code:

Section(header: Text("Amount per person")) {
            TextField("Amount", text: $checkAmount)
        }

The second challenge was a little bit more complicated. You would need to create a new variable that would calculate the amount due in total before dividing it up between the number of people and then displaying the result to a new Text object.

The third challenge stumped me at first. I ended up thinking it was more complicated than it was. After walking away and thinking about it, I realized the problem was quite simple. Similar to the amount field, you would take the String that is generated by the entered text and convert it to an int that way, you can then do the mathematical processing to solve for the tip and overall total, adding nil coalescing or ?? to provide a default value of 0 if for any reason the string that is entered returns anything other than a number.

var totalPerperson: Double {
        let peopleCount = Double(numberOfPeople) ?? 0
}

in the totalPerson variable.

Day 4 (Day 19)

Today is the first challenge day of the course. The challenge was to create an application that handles unit conversions. The types of conversion needed support are:

  • Temperature conversion: users choose Celsius, Fahrenheit, or Kelvin.
  • Length conversion: users choose meters, kilometers, feet, yards, or miles.
  • Time conversion: users choose seconds, minutes, hours, or days.
  • Volume conversion: users choose milliliters, liters, cups, pints, or gallons.

These challenges are crucial to making sure that you understand the complexities of Swift and SwiftUI. So with my long to-do list, I got started.

The interface is simple. Using the Form, I added the Input TextField and The output Text along with controls to switch the type of conversion. Then Created the @State variable and allowed the TextField to have 2-way binding. After setting this up, it is all about creating an if statement with a switch case for each conversation type returning the value after doing the calculation. If the input and output are the same types, such as meters to meters, output the input number’s value with no calculation applied.

Week one.

This has been a fantastic week to learn and start developing using this new platform. I cannot wait to see what next week’s course work is. I am stopping at day four due to the transition to a new project starting tomorrow, and that deserves a fresh blog post. 🤗 Thanks for taking the time to read and keep up with my adventures in learning SwiftUI. See you next week!