I struggle with learning MVVM architecture. My problem is that I can't send data to the next VC.
App idea: I have 2 view controllers. In first VC user sets own parameteres (height and weight with UISlider). Later app presents second VC where user has got information about BMI.
MODEL
struct BMI {
let value: Float
let advice: String
let color: UIColor
let diagnosis: String
}
VIEW MODEL
protocol BmiViewControllerDelegate: class {
func getCalculatedBMI(newBmi: BMI)
}
protocol BmiViewModelDelegate: class {
func sendValue(height: Float?, weight: Float?)
}
class BmiViewModel: BmiViewModelDelegate {
var bmiModel = BmiCalculator()
var bmi: BMI
weak var delegateVC: BmiViewControllerDelegate?
func sendValue(height: Float?, weight: Float?) {
guard let height = height, let weight = weight else { return }
calculateBmi(height: height, weight: weight)
}
func calculateBmi(height: Float, weight: Float) {
let bmiValue = weight / pow(height, 2)
if bmiValue < 18.5 {
bmi = BMI(value: bmiValue, advice: "You should eat more calories", color: .red, diagnosis: "Underweight")
delegateVC?.getCalculatedBMI(newBmi: bmi!)
} else if bmiValue < 24.9 {
bmi = BMI(value: bmiValue, advice: "Your weight is great! Keep it up!", color: .green, diagnosis: "")
delegateVC?.getCalculatedBMI(newBmi: bmi!)
} else {
bmi = BMI(value: bmiValue, advice: "You should eat less calories", color: .red, diagnosis: "Overweight")
delegateVC?.getCalculatedBMI(newBmi: bmi!)
}
}
}
VIEW CONTROLLER
class BMIViewController: UIViewController {
var bmiViewModel = BmiViewModel()
@IBOutlet weak var heightLabel: UILabel!
@IBOutlet weak var heightSlider: UISlider!
@IBOutlet weak var weightLabel: UILabel!
@IBOutlet weak var weightSlider: UISlider!
@IBOutlet weak var calculateButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
bmiViewModel.delegateVC = self
heightSlider.value = 1.5
weightSlider.value = 80
}
@IBAction func heightSliderChanged(_ sender: UISlider) {
let height = String(format: "%.2f", sender.value)
heightLabel.text = "\(height)m"
}
@IBAction func weightSliderChanged(_ sender: UISlider) {
let weight = String(format: "%.0f", sender.value)
weightLabel.text = "\(weight)kg"
}
@IBAction func calculateButtonTapped(_ sender: UIButton) {
let height = heightSlider.value
let weight = weightSlider.value
bmiViewModel.sendValue(height: height, weight: weight)
}
}
extension BMIViewController: BmiViewControllerDelegate {
func getCalculatedBMI(newBmi: BMI) {
let bmiResult = BMIResultViewController()
bmiResult.bmiValue = String(newBmi.value)
bmiResult.advice = newBmi.advice
bmiResult.diagnosis = newBmi.diagnosis
bmiResult.color = newBmi.color
}
I've tried to print values in getCalculatedBMI and these values exists, so why when I open BMIResultViewController values are empty.
And I have one additional question: if force unwrapped bmi values in "delegateVC?.getCalculatedBMI(newBmi: bmi!)" isn't bad approach?