Last active
December 7, 2018 08:00
-
-
Save aranasaurus/9ffd0d2ec2b80780fca754451a9141d8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
enum UnitType: String { | |
case milligrams = "mg" | |
case grams = "g" | |
case kilograms = "kg" | |
case count = "count" | |
case pounds = "lb" | |
case ounces = "oz" | |
case milliliters = "ml" | |
case liters = "L" | |
case cups = "cup" | |
case teaspoons = "tsp" | |
case tablespoons = "tbsp" | |
static let dryUnits: [UnitType] = [.count, .milligrams, .grams, .kilograms, .pounds, .ounces] | |
static let liquidUnits: [UnitType] = [.milliliters, .liters, .cups, .teaspoons, .tablespoons] | |
var weights: [String] { | |
var weights = ["Select Amount"] | |
switch self { | |
case .milligrams, .ounces, .teaspoons, .tablespoons, .count: | |
for i in 1 ... 100 { | |
weights.append(String(i)) | |
} | |
case .kilograms, .liters: | |
for i in stride(from: 0.05, to: 5.05, by: 0.05) { | |
let val = String(format: "%.2f", i) | |
weights.append(val) | |
} | |
case .cups, .pounds: | |
for i in stride(from: 0.25, to: 5.25, by: 0.25) { | |
let val = String(format: "%.2f", i) | |
weights.append(val) | |
} | |
case .grams, .milliliters: // grams // RA: changed this from `default:`, not sure if you meant for milliliters to be using this case, but that's how the code was written, and shows why you should avoid using `default` ;) | |
for i in 1...100 { | |
weights.append(String(i)) | |
} | |
for i in stride(from: 110, to: 1010, by: 5) { | |
weights.append(String(i)) | |
} | |
} | |
return weights | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
class WeightPickerView: UIPickerView, UIPickerViewDelegate, UIPickerViewDataSource { | |
typealias SelectedRowClosure = (Int) -> Void | |
typealias TouchersBegan = () -> Void | |
var selectedRowClosure: SelectedRowClosure = { _ in } | |
var touchesBegan: TouchersBegan = { _ in } | |
fileprivate var pickerWeights = [String]() | |
var pickerUnitTypes: [UnitType] = [.grams, .milligrams, .kilograms, .count, .liters, | |
.pounds, .ounces, .cups, .teaspoons, .tablespoons] | |
func numberOfComponents(in pickerView: UIPickerView) -> Int { | |
return 2 | |
} | |
func pickerView(_ pickerView: UIPickerView, | |
numberOfRowsInComponent component: Int) -> Int { | |
if component == 0 { | |
return pickerWeights.count | |
} else { | |
return pickerUnitTypes.count | |
} | |
} | |
func pickerView(_ pickerView: UIPickerView, | |
titleForRow row: Int, | |
forComponent component: Int) -> String? { | |
if component == 0 { | |
return pickerWeights[row] | |
} else { | |
return pickerUnitTypes[row].rawValue | |
} | |
} | |
// MARK: pickerView(_:didSelectRow:inComponent:) | |
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { | |
touchesBegan() // I'd like to move this elsewhere, but not sure where :( | |
if component == 0 { | |
selectedRowClosure(row) | |
} else { | |
pickerWeights = pickerUnitTypes[row].weights | |
// Change what's shown in the 1st component based on selected unit in the 2nd component. | |
pickerView.reloadComponent(0) | |
} | |
} | |
} | |
extension WeightPickerView { | |
// Selects row, triggering `didSelectRow` function that changes the 1st component | |
private func pick(row: Int, inComponent component: Int) { | |
selectRow(row, inComponent: component, animated: false) | |
pickerView(self, didSelectRow: row, inComponent: component) | |
} | |
// Makes sure that units in 1st component are shown (only used in `viewDidLoad()`) | |
func configureInitialRows() { | |
pickerView(self, didSelectRow: 0, inComponent: 1) | |
} | |
// Selects rows in picker view based on parameters | |
func pickRowsFor(unit: UnitType, weight: Double) { | |
let unitRow = pickerUnitTypes.index(of: unit) ?? 0 | |
pick(row: unitRow, inComponent: 1) | |
let weightInt = Int(weight) // Int(exactly: weight) didn't compile for me, so I just removed it... -RA | |
if let row = pickerWeights.index(of: "\(weightInt)") { | |
pick(row: row, inComponent: 0) | |
} else if let row = pickerWeights.index(of: String(format: "%.2f", weight)) { | |
pick(row: row, inComponent: 0) | |
} | |
} | |
func selectedUnitType() -> UnitType { | |
let row = selectedRow(inComponent: 1) | |
return pickerUnitTypes[row] | |
} | |
func selectedWeight() -> Double? { | |
let row = selectedRow(inComponent: 0) | |
let weight = pickerWeights[row] | |
return Double(weight) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment