サイトアイコン BergamotMagic

おそるおそるSwift 2-4 デンタッキー(電卓)を作る ~電卓らしく計算させる機能を追加する~

Swift5+Xcode11.6

シリーズ2の4回目です。

今回のゴール

 続きです。下の動画のように、一端の電卓として機能するように、計算させる機能を追加します。コードはContentView.swiftに書きました。

https://bergamotmagic.tokyo/wp-content/uploads/2020/08/32149a5e04496ad54c69aba524355a76.mp4
プレビュー

 後半は変更がないので省略しています。

import SwiftUI

struct ContentView: View {
    @State var inputArray :[String] = []    //リスト表示用
    @State var inputStr :String = "" 
    let CalStr :[String] = ["+","-"]    //計算記号一覧
    
    func outputStr(tmpStr :String) {
        //        var str1 :String = ""
        if tmpStr == "C" {
            self.inputStr = ""
            self.inputArray = []
        } else if tmpStr == "=" {
            var tmpStr2 :String = ""     //配列の文字をキャッシュ
            var tmpResult :Double = 0.0 //計算途中の数値をキャッシュ
            var symbol :String   //四則計算の区別
            
            self.inputArray.append(self.inputStr)
            self.inputStr = tmpStr
            
            for item in self.inputArray {
                let str = item
                let start1 = str.startIndex     //配列要素の最初の文字を取得
                symbol = String(str[start1])
                //それが計算記号に該当しない場合とする場合で処理振り分け
                if self.CalStr.contains(symbol) == false {
                    tmpResult = atof(item)  //atofは文字列をDoubleに変換する関数
                } else {
                    tmpStr2 = String(str.suffix(item.count - 1))
                    switch symbol {
                    case "+":
                        tmpResult += atof(tmpStr2)
                    case "-":
                        tmpResult -= atof(tmpStr2)
                    default:
                        tmpResult = 9999999.0
                    }
                }
                print("Aポイント: item:\(item) tmpStr2:\(tmpStr2) tmpResult:\(tmpResult)")
            }
            self.inputStr = String(tmpResult)
        } else if (self.CalStr.contains(tmpStr))&&(inputStr != "") {
            self.inputArray.append(self.inputStr)
            self.inputStr = tmpStr
            print("Bポイント:配列に追加しました。")
            for item in inputArray {
                print("現在の配列の状況は、\(item)")
            }
        } else {
            self.inputStr += tmpStr
            print("Cポイント:文字を追加しました。追加した文字は、\(self.inputStr)")
        }
    }

    var body: some View {
        VStack {
            Text("\(self.inputStr)")
                .font(.largeTitle)
                .fontWeight(.heavy)
                .foregroundColor(Color.red)
                .multilineTextAlignment(.trailing)
                .frame(width: 300.0)

 「計算させるだけ」なのですが、処理がいきなり複雑になっています。まず、条件分岐を効率的にするために四則計算記号を値とする配列CalStrを作りました。とりあえず、加減記号しか入れていませんが、この配列に他の記号を追加して、後で説明する分岐部分で計算式を入力すれば、いかなる計算もできるようになります。
 デバッグ画面を見ると、どのように動作しているか把握しやすいと思います。

https://bergamotmagic.tokyo/wp-content/uploads/2020/08/f7ba29d06290566d6469216ead4f7cfa.mp4
デバック画面

 ”=”が押されると、配列の各要素をループさせて、次の処理を行います。
(1) 配列の最初の文字を確認し、計算記号であれば、その計算記号を変数symbolに入れます。計算記号でない場合は、そのまま配列の値を計算途中結果を格納する変数tmpResultに入れます。これは、基本的に最初の値に対応するための処理です。if文のcontainsという条件式は覚えないといけませんね。また、atofは文字列をダブル型に変更する関数です。文字列は計算できませんから必要です。
(2)  計算記号の場合は、symbolから値を読み、その内容に応じて処理を分岐させています。
(3) ループが終わったときのtmpResultが総計になりますので、それをinputStrに代入して、画面に表示させます。
 上の動画では最後になってしまっていますが、”Cポイント”となっている部分が、以上の処理結果の表示になります。
 他に、計算記号が入力されたときは”Bポイント”となっている部分が処理結果、数字が入力されたときは”Cポイント”となっている部分が処理結果の表示となっています。

次回は

 最終形である、プリンタ機能部分を追加します。うまくできるでしょうか!?

モバイルバージョンを終了