Skip to content

Instantly share code, notes, and snippets.

@scottswezey
Last active August 13, 2020 10:24
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save scottswezey/515246fe859d45751b0a4894333121ab to your computer and use it in GitHub Desktop.
Save scottswezey/515246fe859d45751b0a4894333121ab to your computer and use it in GitHub Desktop.
My solution for #100DaysOfSwiftUI day 19
import SwiftUI
enum UnitTypes: CaseIterable, Hashable, Identifiable {
case temperature
case length
case time
case volume
var name: String { "\(self)".capitalized }
var id: UnitTypes { self }
var subTypes: [Dimension] {
switch self {
case .temperature:
return [UnitTemperature.celsius, UnitTemperature.fahrenheit, UnitTemperature.kelvin]
case .length:
return [UnitLength.meters, UnitLength.kilometers, UnitLength.feet, UnitLength.yards, UnitLength.miles]
case .time:
return [UnitDuration.seconds, UnitDuration.minutes, UnitDuration.hours, UnitLength(symbol: "day", converter: UnitConverterLinear(coefficient: 86_400))]
case .volume:
return [UnitVolume.milliliters, UnitVolume.liters, UnitVolume.cups, UnitVolume.pints, UnitVolume.gallons]
}
}
}
struct ContentView: View {
@State private var input: String = ""
@State private var unitType: UnitTypes = UnitTypes.length {
willSet {
inputUnit = newValue.subTypes[0]
outputUnit = newValue.subTypes[1]
}
}
@State var inputUnit: Dimension = UnitLength.feet
@State var outputUnit: Dimension = UnitLength.meters
private var inputValue: Double { Double(input) ?? 0 }
var output: String {
let measurement = Measurement(value: inputValue, unit: inputUnit)
return "\(measurement.converted(to: outputUnit))"
}
var body: some View {
NavigationView {
Group {
Form {
Section {
Picker(selection: $unitType, label: Text("Unit category")) {
ForEach(UnitTypes.allCases) { unit in
Text(unit.name)
}
}.pickerStyle(SegmentedPickerStyle())
HStack {
TextField("Input", text: $input)
.keyboardType(.decimalPad)
Divider()
Picker(selection: $inputUnit, label: Text("Type:")) {
ForEach(unitType.subTypes, id: \.self) { type in
Text(type.symbol)
}
}
}
}
Section(header: Text("Converted to")) {
Picker(selection: $outputUnit, label: Text("Output type")) {
ForEach(unitType.subTypes, id: \.self) { type in
Text(type.symbol)
}
}.pickerStyle(SegmentedPickerStyle())
Text("Result: ") + Text(output)
}
}
}.navigationBarTitle("Unit Converter")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
@scottswezey
Copy link
Author

I am still working on bugs in the pickers and the unitType willSet property. My intention is that changing the unitType @State property would set sensible defaults for the input and output type @State properties. Unfortunately, the willSet doesn't seem to have any impact.

Additionally, the outputType picker retains some extraneous options after changing the unitType picker.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment