// // 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() } }