Skip to content

Instantly share code, notes, and snippets.

@surakamy
Created October 12, 2019 20:15
Show Gist options
  • Save surakamy/0e8bb35f6ad5a8145c18d6fd79a1a58a to your computer and use it in GitHub Desktop.
Save surakamy/0e8bb35f6ad5a8145c18d6fd79a1a58a to your computer and use it in GitHub Desktop.
//
// ContentView.swift
// UnitCoverter
//
// Created by roblack on 10/12/19.
// Copyright © 2019 roblack. All rights reserved.
//
/// TODO: remove ContentViewUnitExtensions.swift
import SwiftUI
class Converter: ObservableObject {
var units: [[UnitType]] = [
[.meters, .kilometers, .feet, .yards, .miles],
[.Celsius, .Fahrenheit, .Kelvin],
[.seconds, .minutes, .hours, .miliseconds, .microseconds],
[.milliliters, .liters, .cups, .pints, .gallons]
]
var inputUnitTypes: [UnitType] = [.length, .temperature, .time, .volume]
var input = "" {
didSet { converting() }
}
var unit = 0 {
didSet {
changeDimetion()
converting()
}
}
var inputUnit = 0 {
didSet { converting() }
}
var outputUnit = 0 {
didSet { converting() }
}
var selected: [UnitType] {
return units[unit]
}
@Published var output: String = ""
func changeDimetion() {
inputUnit = 0
outputUnit = 0
}
func converting() {
guard let input: Int = Int(input) else { output = "0"; return }
let inUnit = selectedUnit(units[unit][inputUnit])
let outUnit = selectedUnit(units[unit][outputUnit])
let fromValue = Measurement(value: Double(input), unit: inUnit)
let toValue = fromValue.converted(to: outUnit)
output = "\(toValue)"
}
enum UnitType: CustomStringConvertible {
case length, temperature, time, volume
case meters, kilometers, feet, yards, miles
case Celsius, Kelvin, Fahrenheit
case seconds, minutes, hours, miliseconds, microseconds
case milliliters, liters, cups, pints, gallons
var description: String {
switch self {
case .length: return "length"
case .temperature: return "temperature"
case .time: return "time"
case .volume: return "volume"
case .meters: return "meters"
case .kilometers: return "kilometers"
case .feet: return "feet"
case .yards: return "yards"
case .miles: return "miles"
case .Celsius: return "Celsius"
case .Kelvin: return "Kelvin"
case .Fahrenheit: return "Fahrenheit"
case .seconds: return "seconds"
case .minutes: return "minutes"
case .hours: return "hours"
case .miliseconds: return "miliseconds"
case .microseconds: return "microseconds"
case .milliliters: return "mililiters"
case .liters: return "liters"
case .cups: return "cups"
case .pints: return "pints"
case .gallons: return "gallons"
}
}
}
func selectedUnit(_ value: UnitType) -> Dimension {
switch value {
case .meters: return UnitLength.meters
case .kilometers: return UnitLength.kilometers
case .feet: return UnitLength.feet
case .yards: return UnitLength.yards
case .miles: return UnitLength.miles
case .Celsius: return UnitTemperature.celsius
case .Kelvin: return UnitTemperature.kelvin
case .Fahrenheit: return UnitTemperature.fahrenheit
case .seconds: return UnitDuration.seconds
case .minutes: return UnitDuration.minutes
case .hours: return UnitDuration.hours
case .miliseconds: return UnitDuration.milliseconds
case .microseconds: return UnitDuration.microseconds
case .milliliters: return UnitVolume.milliliters
case .liters: return UnitVolume.liters
case .cups: return UnitVolume.cups
case .pints: return UnitVolume.pints
case .gallons: return UnitVolume.gallons
default: return UnitLength.meters
}
}
}
struct ContentView: View {
@ObservedObject var logic = Converter()
var body: some View {
NavigationView {
Form {
Section {
TextField("Input Unit", text: $logic.input)
.keyboardType(.decimalPad)
.multilineTextAlignment(.center)
// MARK: - Unit Picker
Picker("Length", selection: $logic.unit) {
ForEach(0 ..< logic.inputUnitTypes.count) {
Text("\(self.logic.inputUnitTypes[$0].description)")
}
}
.pickerStyle(SegmentedPickerStyle())
}
HStack {
// MARK: - Input Unit Picker
Section(header: Text("From")) {
Picker("Length", selection: $logic.inputUnit) {
ForEach(0 ..< logic.selected.count) {
Text("\(self.logic.selected[$0].description)")
}
}
.pickerStyle(WheelPickerStyle())
.frame(minWidth: 0, maxWidth: .infinity/2, alignment: .center)
}
Section(header: Text("To")) {
// MARK: - Output Unit Picker
Picker("Length", selection: $logic.outputUnit) {
ForEach(0 ..< logic.selected.count) {
Text("\(self.logic.selected[$0].description)")
}
}
.pickerStyle(WheelPickerStyle())
.frame(minWidth: 0, maxWidth: .infinity/2, alignment: .center)
}
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
}
// MARK: - Output
Section {
Text("\(logic.output)")
.frame(minWidth: 0, maxWidth: .infinity, alignment: .center)
}
}
.navigationBarTitle("UnitConverter")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment