The given task is to implement a time-units app. I guess I got the main logic right, but concerning the UI-coding there could be improvements.
Here's my code:
// Time-Units enum
enum TimeUnits: String, CaseIterable {
case seconds = "Seconds"
case minutes = "Minutes"
case hours = "Hours"
case days = "Days"
}
// UI and logic
struct ContentView: View {
@State private var selectedInput = TimeUnits.seconds
@State private var selectedOutput = TimeUnits.seconds
@State private var inputValue: Double? = nil
@State private var outputValue = 0.0
func convertInput() {
outputValue = inputValue ?? 0.0
if var inputValue = inputValue {
switch selectedInput {
case .seconds:
break
case .minutes:
inputValue *= 60.0
case .hours:
inputValue *= (60.0 * 60.0)
case .days:
inputValue *= (60.0 * 60.0 * 24.0)
}
switch selectedOutput {
case .seconds:
outputValue = inputValue
case .minutes:
outputValue = inputValue / 60.0
case .hours:
outputValue = inputValue / (60.0 * 60.0)
case .days:
outputValue = inputValue / (60.0 * 60.0 * 24.0)
}
}
}
var body: some View {
VStack {
Text("Time-Units Converter")
.font(.title)
Form {
Section {
TextField(
"Value to convert",
value: $inputValue,
format: .number
)
.keyboardType(.decimalPad)
UnitPickerView(selectedUnit: $selectedInput)
} header: {
Text("Input")
.font(.title2)
}
Section {
UnitPickerView(selectedUnit: $selectedOutput)
Text("\(String(format: "%.2f", inputValue ?? 0.0)) \(selectedInput.rawValue) > \(String(format: "%.2f", outputValue)) \(selectedOutput.rawValue)")
.font(.title3)
.bold()
} header: {
Text("Output")
.font(.title2)
}
}
}
.onChange(of: selectedInput) {
convertInput()
}
.onChange(of: selectedOutput) {
convertInput()
}
.onChange(of: inputValue) {
convertInput()
}
}
}
// UI-logic used in multiple places
struct UnitPickerView: View {
@Binding var selectedUnit: TimeUnits
var body: some View {
Picker("Please selected the input-unit", selection: $selectedUnit) {
ForEach(TimeUnits.allCases, id: \.self) { unit in
Text(unit.rawValue)
}
}.pickerStyle(.segmented)
}
}
Is there a way to get rid of the three-times onChange-modifier? Should I avoid the approach completely and doing something else instead?
The way I'm handling the result-output: Is it a good idea or should I alter it?
What are your thoughts concerning my coding in general? What would you have done differently and why?