import UIKit
class ConversionViewController: UIViewController, UITextFieldDelegate {
// MARK: - IBOutlet
@IBOutlet var celsiusLabel: UILabel!
@IBOutlet var textField: UITextField!
var fahrenheitValue: Measurement<UnitTemperature>? {
didSet {
updateCelsiusLabel()
}
}
var celsiusValue: Measurement<UnitTemperature>? {
if let fahrenheitValue = fahrenheitValue {
return fahrenheitValue.converted(to: .celsius)
} else {
return nil }
}
let numberFormatter: NumberFormatter = {
let nf = NumberFormatter()
nf.numberStyle = .decimal
nf.minimumFractionDigits = 0
nf.maximumFractionDigits = 1
return nf
}()
// MARK: - IBAction
@IBAction func fahrenheitFieldEditingChanged(_ textField: UITextField) {
if let text = textField.text, let value = Double(text) {
fahrenheitValue = Measurement(value: value, unit: .fahrenheit)
} else {
fahrenheitValue = nil
}
}
@IBAction func dismissKeyboard(_ sender: UITapGestureRecognizer) {
textField.resignFirstResponder()
}
// MARK: - UIViewController Method
override func viewDidLoad() {
super.viewDidLoad()
updateCelsiusLabel()
}
// MARK: - Utility Method
func updateCelsiusLabel() {
if let celsiusValue = celsiusValue {
celsiusLabel.text = numberFormatter.string(from: NSNumber(value: celsiusValue.value))
} else {
celsiusLabel.text = "???"
}
}
// MARK: - UITextFieldDelegate Method
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let existingTextHasDecimalSeparator = textField.text?.range(of: ".")
let replacementTextHasDecimalSeparator = string.range(of: ".")
let replacementTextHasMinusForBelowZero = string.range(of: "-") // my add for the Bronze Challenge
// isSuperset(of:) won't work anymore properly with NSCharacterSet, therefore I replaced it with CharacterSet
let numericOnly = CharacterSet.decimalDigits // my add for the Bronze Challenge
let myStringSet = CharacterSet(charactersIn: string) // my add for the Bronze Challenge
if existingTextHasDecimalSeparator != nil && replacementTextHasDecimalSeparator != nil /* // my add for the Bronze Challenge */ || numericOnly.isSuperset(of: myStringSet) == false && replacementTextHasDecimalSeparator == nil && replacementTextHasMinusForBelowZero == nil {
return false
}
else {
return true
}
}
}