[iOSアプリ開発] BMI計算アプリ

iPhoneで動く「BMI計算アプリ」を作ってみませんか?

身長、体重の値をUIスライダーを使って入力しボタンを押すと、次画面に移動し、BMI計算結果やアドバイスなどが表示される初心者向けの簡単なアプリです。

目次

概要

この講座で学習する内容
  • BMI計算アプリを作成

アプリを作成する過程で、以下の内容を学習できます。

  • segueを使った画面遷移
  • クラスのダウンキャスティング(as!
  • オプショナルの値を確認し、コードに組み込む方法(5通り)
  • UIスライダーの使い方

MVCデザインパターンを適用しています。
Model(M)、View(V)、Controller(C
記事中、M、V、Cの略を使用しています。

参考にした講座】iOS & Swift – The Complete iOS App Development Bootcamp (Udemy)
 (Section11) Advanced Swift Programming – Classes, Inheritance & Advanced Optionals

この講座で作成するアプリの概要
  • 身長、体重の値をUIスライダーを使って入力します。
  • 身長、体重の値はラベルで表示され、スライダーを動かすことで、表示される数値も変更されます。
  • CALCULATEボタンを押すと、BMIを計算し、次画面に移動し、その結果を表示します。
  • 次画面において、RECALCULATEボタンを押すと前画面に戻り、再計算できます。
  • BMIの計算結果により、アドバイスの文章、背景色が変わります。(3パターン)
アプリの開発環境(2023年5月2日現在)
  • Xcode: Version 14.3
  • macOS: Venture: Version 13.3.1
  • iOS: 16.4.1
GitHubからプロジェクトを入手したい方はこちら
Xcodeのインストールが未了の方はこちら
GitHubからXcodeプロジェクトをクローンする方法はこちら

GitHubにアクセス後、「Code」をクリックし、赤枠で囲まれたURLをコピーします。

Xcodeを起動後、赤枠で囲まれた「Clone an existing project」をクリックします。

先ほどコピーしたURLを入力箇所にペーストし、Cloneボタンをクリックすれば、クローン完成です。

UIの設定

開始プロジェクトをクローンしました。早速、Xcodeの中のプロジェクトを確認してみます。

開始プロジェクトの確認

開始プロジェクトの確認
  • Models(空)、Views(Main.storyboard)、Controllers(ViewControllers.swift)のフォルダはすでに作成されています。
  • 2画面あります。
  • 1つ目の画面は、身長(height)、体重(weight)を設定するUIスライダが配置されており、その下に計算(CALCULATE)ボタンがあります。
  • 2つ目の画面は、計算結果の表示、再計算(RECALCULATE)ボタンがあります。

UIスライダの設定

UIスライダを属性インスペクタで設定する

属性インスペクタ設定

図のように、初期値、最大値、最小値が設定できます。

  • Value: 初期値
  • Maximum: 最大値
  • MiniMum: 最小値

UIスライダを動かして、身長・体重の値を出力する

STEP
デザインとコードのリンク

UIスライダーをViewControllerから操作できるようにリンクを作成します。

Height,Weightそれぞれ、IBActionリンクを作成します
STEP
身長・体重の値を出力

次のようにコードを追加しました。スライダを動かすと、身長、体重の値が出力されることが確認できます。

 @IBAction func heightSliderChanged(
    _ sender: UISlider) {
    print(sender.value)
 }
    
@IBAction func weightSliderChanged(
    _ sender: UISlider) {
    print(sender.value)
}
STEP
桁を補正して身長・体重の値を出力

身長は小数点以下2位(四捨五入)、体重は整数表示するようにコードを追加します。

 @IBAction func heightSliderChanged(
    _ sender: UISlider) {
    print(String(format: "%.2f", 
        sender.value))
}
    
@IBAction func weightSliderChanged(
    _ sender: UISlider) {
    print(String(format: "%.0f", 
        sender.value))
}

UIスライダを動かして、身長・体重の値をラベルに表示

STEP
デザインとコードのリンク

身長、体重の数値を表示するラベルをViewControllerから操作できるようにリンクを作成します。

heightLabel,weightLabelそれぞれリンクを作成します。
STEP
ラベルに身長・体重の値を表示(単位をつける)

スライダーを動かした時の身長・体重の値をラベルに表示させます。
表示する値の後ろに身長は「m」、体重は「kg」の単位をつけます。

BMIの計算結果を出力する

CALCULATEボタンを押した時、身長、体重の数値を読み取り、BMIを計算し、その計算結果を出力させます。

STEP
デザインとコードをリンクする
  • CALCULATEボタンとコードをリンクする
  • 身長・体重の値を読み取れるようにリンクを作成する
    IBActionの中の変数(height、weight)の値は、外から読み取れない!
STEP
BMIを計算し、出力する(pow使用)

BMI = 体重 / (身長 × 身長)で計算される。

身長 × 身長は、pow関数を使用して計算する

pow関数
pow(value, n)   // value の n乘 (一般形)

pow(height, 2)  // height の2乘
身長165cm、体重48kgの時、BMI=17.686245と出力されました

BMI計算結果を次画面へ表示させる

BMIの計算結果を次画面に表示させましょう。

次画面(2つ目の画面)Viewの設定

次画面Viewファイルの作成

次画面のViewファイルを作成します。Xcodeメニュー「File」→「New File」を選択します。

Cocoa Touch Class」を選択し、Nextボタンを押します。
Class名を「ResultViewController」に変更し、Nextボタンを押します。

作成したViewを次画面のViewとして認識させる

次画面の左上にある丸印をクリック
→Xcode右上の四角の印をクリック
→CustomClassのClassから先程作成した「Result ViewController」を選択しEnterキーを押します。
次画面のデザインとコードをリンクさせます

前画面(1つ目の画面)の名前を一括変更

ViewControllerという名前を使用しているすべての場所を検出しCalculateViewControllerに一括変更します。

ViewControllerを右クリック
→「Refacor」→「Rename」を選択します
CalculateViewControllerに変更後、Renameボタンを押します

次画面への遷移

Segueの設定(次画面への遷移開始)

ctrlキーを押しながら、CalculateViewController→ResultViewController へドラッグ
→表示される画面から「Present Modally」を選択します
Identifierには、「goToResult」と入力します

performSegue関数を使って、次画面への遷移をします。

Xcodeで設定したIdentifier:「goToResult」と
performSegue関数内のwithIdentifier:「goToResult」を必ず一致させること。

identifierには、先程設定した「goToResult」を入力します
次画面へ遷移しました。

BMIの値を次画面へ送る

BMIの値を受け渡しするため、以下のように送る側、受取る側のコードを書きます。

送る側(CalculateViewController)
override func prepare(for segue: UIStoryboardSegue, 
    sender: Any?) {
    if segue.identifier == "goToResult" {
        let destinationVC = 
            segue.destination as! ResultViewController
        destinationVC.bmiValue = bmiValue
    }
}
受取る側(ResultViewController)
class ResultViewController: UIViewController {
    
    var bmiValue: String?
    override func viewDidLoad() {
        super.viewDidLoad()
        bmiLabel.text = bmiValue
    }
}

prepareメソッドをoverrideして、BMIの値を次画面へ送付しています。
as!を使用して、segue.destinationをResultViewControllerにダウンキャスティングしています。

その結果、以下のように、BMIの値を次画面に送ることができるようになりました。
例)身長1.72m、体重61kgの時、BMIが20.6であることが表示されています。

起動画面(CalculateViewController)
計算結果を表示する画面(ResultViewController)

前画面に戻るには?

前画面に戻るには、IBActionの中で、dismiss関数を記載すれば、recalculateボタンをクリックすると戻ることができます。

計算結果を表示する画面(ResultViewController)
@IBAction func recalculatePressed(_ sender: Any) {
    self.dismiss(animated: true, completion: nil)
}

BMIの計算結果によりアドバイス文、背景色を変更する

MVCデザインパターンの導入

現在、ViewController(V)の中で、BMIを計算→桁補正などを行っている。

これから、BMIの計算結果によって、背景色やアドバイスの文章を変更しますが、このまま続けるとViewControllerのコード量が多くなりすぎ、読みにくくなるため、MVCデザインパターンを取り入れることにします。

MVCデザインパターンの導入
CalculateViewController(C)起動画面

ViewControllew(C)の中にあった、以下の機能を新設したClaculatorBrain(M)に移動した。

  • BMIの計算
    →メソッドcalculateBMI()作成
  • BMIの桁補正
    →メソッドgetBMIValue()作成
CalculatorBrain(M)

BMIの初期値を0.0から?(オプショナル)に変更

現在、bmiの初期値は0.0となっている。

しかし、BMIは、身長と体重の数値が入力された後、計算されて数値が入力されるものであるから、以下のように変更してみた。

(変更前)var bmi: Float = 0.0
(変更後)var bmi: Float?

ところが、次のようなエラーが出ることになる。

このエラーの解決法はいくつか考えられる。この中で最もシンプルな解決法3を選択することにします。

var bmi: Float?

func getBMIValue() -> String {
    let bmiTo1DecimalPlace = String(format: "%.1f", bmi)
    return bmiTo1DecimalPlace
}

(エラー)Value of optional type ‘Float?’ must be unwrapped to a value of type ‘Float’

BMIの構造体を作成する

BMIの値、アドバイス、背景色を格納する構造体を作成し、これに対応するようにコードを修正します。

BMI構造体
import UIKit

struct BMI {
    let value: Float
    let advice: String
    let color: UIColor
}
CalculatorBrain(M)コード修正
struct CalculatorBrain {
    
    var bmi: BMI?
    
    mutating func calculateBMI(
        height: Float, weight: Float) {
        let bmiValue = weight / pow(height, 2)
    }
    
    func getBMIValue() -> String {
        let bmiTo1DecimalPlace = 
        String(format: "%.1f", bmi?.value ?? 0.0)
        return bmiTo1DecimalPlace
    }
}

BMIの計算結果によりアドバイス文、背景色を設定する条件文を作成する

以下の条件文のコードを追記します。

CalculatorBrain(M)条件文の追記
if bmiValue < 18.5 {
    bmi = BMI(value: bmiValue, 
              advice: "たくさん食べてください", 
              color: UIColor.blue)
} else if bmiValue < 24.9 {
    bmi = BMI(value: bmiValue, 
              advice: "このままの状態を維持しましょう", 
              color: UIColor.green)
} else {
    bmi = BMI(value: bmiValue, 
              advice: "食べる量を減らしましょう", 
              color: UIColor.red)
}

(完成)BMIの計算結果によりアドバイス文、背景色を変更する

BMIの計算結果により、計算結果を表示する画面でアドバイス文を表示させ、背景色を変更するようにコードを修正した。

CalculateViewController(C)起動画面
CalculatorBrain(M)から
アドバイス文はメソッドgetAdvice()
背景色はメソッドgetColor()
から入手し、その結果を
ResultViewController(C)に送信
CalculatorBrain(M)
メソッドgetAdvice()はアドバイス文、
メソッドgetColor()は背景色
を返すreturn
計算結果を表示する画面(ResultViewController)
アドバイス文の値はadviceラベルに表示
背景色の値はview.backgroundに反映させる

この記事が気に入ったら
いいね または フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次