10日目：アプリ開発途中でわかったことを綴るメモ

#10日目のアプリ ：BMIアプリ

MVCの形で作成。

##パーツとして再利用できそうなもの
▼▼▼Controller(ResultViewController.swift)


```

import UIKit

//viewへのコントロールを記述する
class ResultViewController: UIViewController {
    
    //計算結果は　nilかもしれないから、？　をつけておくことがいいかも。
    var bmiValue: String?
    var advice: String?
    var color: UIColor?

    @IBOutlet weak var bmiLabel: UILabel!
    @IBOutlet weak var adviceLabel: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        //計算結果の数値、アドバイス、背景色を変える。
        bmiLabel.text = bmiValue
        adviceLabel.text = advice
        view.backgroundColor = color
    }
    
    //画面を閉じるボタンを押したら画面を閉じる時のコード
    @IBAction func recalculatePressed(_ sender: UIButton) {
        dismiss(animated: true, completion: nil)
    }
    

}


```

もう一つ、View。

▼▼▼Controller(CalculateViewController.swift)


```

import UIKit

class CalculateViewController: UIViewController {
    
    //計算ロジックはモデルにあるものをもってくる。そのためにまず変数に入れる。
    var calculatorBrain = CalculatorBrain()

    //ラベルとスライダーを紐付け
    @IBOutlet weak var heightLabel: UILabel!
    @IBOutlet weak var weightLabel: UILabel!
    @IBOutlet weak var heightSlider: UISlider!
    @IBOutlet weak var weightSlider: UISlider!
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func heightSliderChanged(_ sender: UISlider) {
        //スライダーのvalueを小数点2位で定数heightに格納して、ラベルに表示する。
        let height = String(format: "%.2f", sender.value)
        heightLabel.text = "\(height)m"
    }
    
    @IBAction func weightSliderChanged(_ sender: UISlider) {
        //スライダーのvalueを小数点0位で定数weightに格納して、ラベルに表示する。
        let weight = String(format: "%.0f", sender.value)
        weightLabel.text = "\(weight)Kg"
    }
    
    @IBAction func calculatePressed(_ sender: UIButton) {
        //計算ボタンを押したら、スライダーの値を各定数（height , weight）に格納
        let height = heightSlider.value
        let weight = weightSlider.value

        //計算はModelに値を渡す。初めに設定した var calculatorBrain = CalculatorBrain() を利用
        calculatorBrain.calculateBMI(height: height, weight: weight)
        //上記で計算された結果が返ってくる。
        
        //結果をセグエ"goToResult"へ持たせてあげる。
        performSegue(withIdentifier: "goToResult", sender: self)
        
    }
        //結果を見るボタンを押したときに、該当するセグエがあったら処理する。を記述。
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        
        //もしセグエが"goToResult"だったら以下をする。
        if segue.identifier == "goToResult" {
            
            //定数を作って、それに値を入れて、計算結果ResultViewControllerの変数に渡してあげる準備。
            let destinationVC = segue.destination as! ResultViewController
            
            //計算結果画面にある変数に計算して返ってきた数値を入れる。
            destinationVC.bmiValue = calculatorBrain.getBMIValue()
            destinationVC.advice = calculatorBrain.getAdvice()
            destinationVC.color = calculatorBrain.getColor()
        }
    }
}

```


▼▼▼Model(BMI.swift)


```
import UIKit

//3つの値は、後でセットとして扱うことで漏れがなくなるし分かりやすくなる
struct BMI {
    let value: Float
    let advice: String
    let color: UIColor
}

```
▼View(Main.Storyboard)
ストーリーボード


▼Model(CalculaterBrain.swift)

```
import UIKit

struct CalculatorBrain {
    
    //セットで使うものをまとめたBMI struct を変数に入れる
    var bmi: BMI?
    
    
    //Modelのstructで定義しているbmiがnilだったら、"0.0"を返す。入っていたらその値String型を返す。
    func getBMIValue() -> String {
        
        //bmiの数値はFloat型。小数点１位に直して、、String型に変更して、定数bmiTo1DecimailPlaceに格納する
        let bmiTo1DecimalPlace = String(format: "%.1f", bmi?.value ?? 0.0)
        //格納した値を返す
        return bmiTo1DecimalPlace
    }
    
    //Modelのstructで定義しているadviceがnilだったら、"No advice"を返す。入っていたらその値String型を返す。
    func getAdvice() -> String {
        return bmi?.advice ?? "No advice"
    }
    
    //Modelのstructで定義しているcolorがnilだったら、白を返す。入っていたらその値UIColor型を返す。
    func getColor() -> UIColor {
        return bmi?.color ?? #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)
    }
    
    //BMIを計算する
    //（）内には、入力されるFloat型を指定。Doubleでもいいかも。
    mutating func calculateBMI(height: Float, weight: Float) {
        
        //BMIの計算式
        let bmiValue = weight / (height * height)
        //ModelのBMI.swiftで定義したstructを利用する。
        if bmiValue < 18.5 {
            bmi = BMI(value: bmiValue, advice: "Eat more pies!", color: #colorLiteral(red: 0.4745098054, green: 0.8392156959, blue: 0.9764705896, alpha: 1))
        } else if bmiValue < 24.9 {
            bmi = BMI(value: bmiValue, advice: "Fit as a fiddle!", color: #colorLiteral(red: 0.721568644, green: 0.8862745166, blue: 0.5921568871, alpha: 1))
        } else {
            bmi = BMI(value: bmiValue, advice: "Eat less pies!", color: #colorLiteral(red: 0.9098039269, green: 0.4784313738, blue: 0.6431372762, alpha: 1))
        }
        
    }
}
```

##感想
MVCのパターンを繰り返し。
もう少しで染みつきそう。