This is an example of how you build your first basic iOS app (calculation app!) with SwiftUI. The idea is to make an app that breakdown user’s financial goal into chunks that is more achievable. Read this article if you want to know more about the project.
That being said, let’s jump into your XCode.
First thing first, open your XCode and make a new project, choose iOS Application without framework. Then, fill in your app’s name. Use the SwiftUI Interface instead of Storyboard. And obviously, use Swift as the language.
The first thing we do is import SwiftUI at the top of the file. This gives us access to all the types and functionality provided by the framework.
Next, we define a struct called ContentView
that conforms to the View
protocol. The View
protocol defines a single requirement: a body property that returns some view content.
import SwiftUI
struct ContentView: View {
var body: some View {
// view content goes here
}
}
Inside the ContentView
struct, declare several @State
properties. The @State
property wrapper is used to store and manipulate state within a view. It automatically generates a setter and a getter for the property, which can be accessed and modified using standard dot syntax (e.g., view.property
).
import SwiftUI
struct ContentView: View {
@State private var goalName = ""
@State private var moneyAmount: Int = 0
@State private var moneyAmountString = ""
@State private var totalAmount: Double = 0.0
@State private var totalAmountString = ""
@State private var inflationRate: Double = 1.04
@State private var targetDate = Date()
@State private var duration: Int = 0
@State private var allocation: Double = 1.0
@State private var allocationString = ""
@State private var result = ""
@State private var aboutPage: Bool = false
@FocusState private var fillingForm: Bool
var body: some View {
//your content goes here
}
}
}
We also declare a @FocusState
property called fillingForm
, which is used to track whether the form is currently being filled out.
Next, define an instance of NumberFormatter
called numberFormatter
to format numbers as currency. Set the numberStyle
property to .currency
, the currencyCode
property to "IDR" for Indonesian rupiah, and the maximumFractionDigits
property to 2 for displaying up to 2 decimal places. Also, set the currencyGroupingSeparator
and currencyDecimalSeparator
properties to specify the characters for the grouping separator and decimal separator, respectively.
import SwiftUI
struct ContentView: View {
@State private var goalName = ""
@State private var moneyAmount: Int = 0
@State private var moneyAmountString = ""
@State private var totalAmount: Double = 0.0
@State private var totalAmountString = ""
@State private var inflationRate: Double = 1.04
@State private var targetDate = Date()
@State private var duration: Int = 0
@State private var allocation: Double = 1.0
@State private var allocationString = ""
@State private var result = ""
@State private var aboutPage: Bool = false
@FocusState private var fillingForm: Bool
private let numberFormatter: NumberFormatter
init() {
numberFormatter = NumberFormatter()
numberFormatter.numberStyle = .currency
numberFormatter.maximumFractionDigits = 2
numberFormatter.currencyCode = "IDR"
numberFormatter.currencyGroupingSeparator = "."
numberFormatter.currencyDecimalSeparator = ","
}
var body: some View {
//your content goes here
}
}
}
Finally, define the body property of the ContentView
struct. It returns a NavigationView
, a container view providing a navigation bar and a hierarchy of views. Inside the NavigationView
, place a Form
view, which is another container view.
This Form
contains three sections: "What your goal is", "What you should prepare", and "Info".
The goal Section
view contains several views:
TextField
for the goal nameTextField
for the amount of moneyDatePicker
for the completion targetPicker
for the inflation rateButton
for calculating the results.var body: some View {
NavigationView{
Form{
// Goal Details
Section("What your goal is"){
TextField("Goal Title", text: $goalName)
.focused($fillingForm)
TextField("Amount of Money", text: $moneyAmountString)
.keyboardType(.decimalPad)
.focused($fillingForm)
.onChange(of: moneyAmountString) { newValue in
let removeCharacters: Set<Character> = ["."]
moneyAmountString.removeAll(where: {removeCharacters.contains($0)})
let length = moneyAmountString.count
if length > 4{
let mySubstring = moneyAmountString.suffix(length - 4)
moneyAmountString = String(mySubstring)
}
moneyAmount = Int(moneyAmountString) ?? 0
moneyAmountString = numberFormatter.string(from: moneyAmount as NSNumber) ?? ""
}
// Completion Date
DatePicker("Completion Target", selection: $targetDate, displayedComponents: .date)
// Inflation Rate
Picker("Inflation Rate", selection: $inflationRate){
Text("3.5%").tag(1.035)
Text("4% (Standard)").tag(1.04)
Text("4.5%").tag(1.045)
}
// Submit Button
HStack{
Spacer()
VStack{
Spacer()
Button("Calculate"){
fillingForm = false
calculation()
}
Spacer()
}
Spacer()
}
}
}
}