【SwiftUI入門講座Part5】消費税計算アプリを作ってみよう~値の計算とTextFieldの使い方~

作成中です。

Part5では、以下のような消費税計算アプリを開発したいと思います。

TextFieldに価格を入力してボタンを押すとその消費税8%と10%が表示されるという簡単なアプリです。

プロジェクト作成

まずはプロジェクトを作成しましょう。

STEP.1
プロジェクトを作成

Xcodeを立ち上げて、Create a new Xcode projectをクリック。

この画面が開かない場合は、command + shift + 1を押してください。

STEP.2
テンプレートを選択

①iOSを選択
②Appを選択
③Nextをクリック

STEP.3
プロジェクトの設定

①Product NameにTaxCalculator
②Interfaceは、SwiftUI
③Languageは、Swift
④全てチェックなし
⑤Nextをクリック

STEP.4
保存するフォルダを選択

Part2で作ったPracticeフォルダを選択してCreateをクリック

これでプロジェクトが作成できました。

レイアウト実装

次にレイアウトを実装しましょう。

完成の見た目はこんな感じです。

TextFieldの下にButtonがあって、その下に3つTextがあるだけの簡単なレイアウトです。

STEP.1

まずは、TextField以外のオブジェクトを配置します。縦並びなのでVStackを使いましょう。

以下のように記載してください。

struct ContentView: View {
    var body: some View {
        VStack {
            Button("計算") {
                
            }
            Text("価格:")
            Text("消費税8%:")
            Text("消費税10%:")
        }
    }
}

STEP.2

次にTextFieldを配置します。

TextFieldを配置する前に、TextFieldに入力された値を保持する変数を宣言します。

struct ContentViewの下に以下の変数を宣言しましょう。

@State var inputText = ""

STEP.3

TextFieldは、以下のように記述します。Buttonの上に記述してください。

TextField("ここに文字を入力", text: $inputText)

コード解説

TextFieldの括弧内の"ここに文字を入力"というところは、そのテキストフィールドが未入力の時にヒントとして表示されます。

text: $inputTextというところは、先ほど宣言した値を$でBindingしています。Bindingについてはのちの講座で解説します。

STEP.4

次に、オブジェクトとオブジェクトの距離が近いので、ちょっとスペースを空けましょう。

VStackを以下のように変更してください。

VStack(spacing: 20) {

これで、オブジェクトの感覚が広がりました。

現状こんな感じになっていれば正解です!

計算の処理を実行

価格を表示する

STEP.1

価格を表示しているTextをかのように変更してください。ちなみにバックスラッシュ(\)はoption + ¥で打てます。

Text("価格:\(inputText)")

STEP.2

これで、Resumeか実行してみると、TextFieldに打った文字が価格の隣に表示されるはずです。

このような感じになっていればOKです。

ボタンを押したら消費税を計算する

STEP.1

まずは、消費税の結果を入れる変数を定義します。

今回は、消費税8%と10%を表示させるので二つの変数を定義します。初期値を0.0にしているので、少数が入るDouble型になります。

@State var tax8 = 0.0
@State var tax10 = 0.0

STEP.2

では、ボタンを押したら入力した価格から消費税を割り出してあげましょう。価格から消費税を割り出す計算式は、消費税8%の場合は、価格 ÷ 0.08です。10%の場合は、価格 ÷ 0.1です。

ではそのように、コードで記述していきましょう。今回は、ボタンの中身に書いていきます。

Button("計算") {
    tax8 = Double(inputText)! * 0.08
}

コード解説

tax8 = Double(inputText) ?? 0 * 0.08

上記のコードは、tax8という変数に、inputTextと0.08を掛けて入れています。

ですが、inputTextは、String型(文字列型)です。しかし、0.08はDouble型です。型が違うと計算ができないので、少数のDouble型か、文字列型のどちらかに型を揃えなければなりません。で、計算するので今回は少数型に揃えます。なので、inputTextDouble()に囲われているわけです。

!マークはオプショナル型というちょっと難しい概念なので、ここでの説明は割愛します。しっかりと意味を理解したい方は以下の記事を確認してみてください。

【Swift】オプショナル型(Optional)について徹底解説~アンラップについても解説「!」「?」「??」、guard let、if let~
STEP.3

同じように消費税10%の方も計算しましょう。

Button("計算") {
    tax8 = Double(inputText)! * 0.08
    tax10 = Double(inputText)! * 0.1
}

これで左上の再生ボタンかcommand + rで実行してみてください。

このようにTextFieldに入力して計算ボタンを押すと消費税8%と消費税10%が計算されます!

バグ修正

現状バグが一点あります。それは、TextFieldに数字以外の文字を入力して計算ボタンを押すと、エラーになることです。エラーになるということは実際にリリースするとアプリがクラッシュしてしまいます。クラッシュするということは絶対に良くないのでなるべくクラッシュしないアプリを作りましょう。

0を代用として使う

現状、数字以外の文字を入れて計算ボタンを押すとエラーになってしまいます。

原因は、tax8 = Double(inputText)! * 0.08の部分です。

ここで計算していて、このinputTextという文字列を少数型に型変換しているのですが、inputTextが数字だと少数型に変換できるのですが、数字以外の文字だと数字に変換されません。なのでエラーになるということです。

以下のように記述してください。

Button("計算") {
    tax8 = (Double(inputText) ?? 0) * 0.08
    tax10 = (Double(inputText) ?? 0) * 0.1
}

! ?? 0に変更するだけでこのエラーは消えます。

どういうことかというと、!だと文字型から少数型に変換失敗したときに、エラーになります。しかし、?? 0だと文字列から少数型に変換失敗した時に、0が代用として使われます。

つまり数字以外の文字が来たときは代用として0が使われるというのがこの対応になります。

数字以外入力させない

数字以外の文字列を入力してもエラーにはならなくなりました。

しかし、そもそもこのアプリで数字以外の文字列を入力する必要はあるのでしょうか?数字を打てれば良いですよね。

なので、数字のみ打てるようにしましょう。

TextFieldに対して、.keyboardType(.numberPad)というモディファイアをつけてください。

TextField("ここに文字を入力", text: $inputText)
    .keyboardType(.numberPad)

こうすることで、数字のキーボードしか使えなくなります。

左上の再生ボタンかcommand + rで実行してください。そして、テキストフィールドにカーソルを合わせてキーボードが出てこない場合は、command + shift + Kを押してください。そうすると画像のように数字しか打てないキーボードが出てくると思います。

これで、そもそも数字でしか打てなくなったので、エラーを未然に防げるようになりました。アプリ開発は、このように色々なエラーに対応していかなければなりません。

import SwiftUI

struct ContentView: View {
    @State var inputText = ""
    @State var tax8 = 0.0
    @State var tax10 = 0.0
    
    var body: some View {
        VStack(spacing: 20) {
            TextField("ここに文字を入力", text: $inputText)
                .keyboardType(.numberPad)
            Button("計算") {
                tax8 = (Double(inputText) ?? 0) * 0.08
                tax10 = (Double(inputText) ?? 0) * 0.1
            }
            Text("価格:\(inputText)")
            Text("消費税8%:\(tax8)")
            Text("消費税10%:\(tax10)")
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}