画面間でデータを受け渡す方法(その2):数値の扱い

Swiftでのデータ型の取り扱いは難しい。この機会にぜひ数値の扱いを学習したい。

画面間でデータを受け渡す簡単な方法を学んだので、
次は第一画面のテキストフィールドに数値をテキスト型で入力して
第二画面に受け渡し、数値型に変換して計算する方法を学ぶ。

受け渡しの方法は前回の(その1)の方法をそのまま用いる。

数値の扱いには細かい規則がたくさんある。
もっとも厄介なのはオプショナル型のデータの取り扱いだ。
今回は体脂肪率を計算するアプリを作って学習することにした。

入力には身長、体重、皮脂厚を用い、BMIと体表面積を求め、さらに体脂肪率を計算する。

入力する値は小数にして、体表面積は身長と体重をべき乗して求め、
結果は小数点以下二桁にして表示する。
画面間に受け渡すテキストデータはオプショナル型なので、アンラップしなければならない。

本当は入力データがnil(空)の場合の対応(例えばif letやguardを用いる)を施さなければならないが、今回は数値の扱いを学習するのが目的なので、オプショナル型<?>を強引に<!>でアンラップする。
安全なアンラップの方法は複雑なので、まだ先の課題にすることにした。

ほぼ一週間かかって何度もやり直し、紆余曲折を経て出来上がりはこんな感じ・・・。

(第一画面:ダミー値が入れてある)

(第二画面:計算結果)

少し、アプリらしい雰囲気になってきたぞ。

この学習で学んだ項目は次のとおり。
1.オプショナル型の取り扱い
2.数値の変換(整数と小数、テキスト型から数値型への変換)
3.べき乗の計算
4.小数の桁数の整理
5.クラッシュの簡単な予防策
<手順:備忘録>
・求める値を計算する<式>を決める。
・必要な入力項目を決める(第1画面に配置)。
・計算の途中で使う仮数を決めておく。
・第2画面で受け取る変数名を決めておき、第1画面に参照できるように貼り付けておく。
・計算途中でデータ型が交錯しないように始めにダミーの値で変数を定義しておく(第2画面)。
・複雑な計算式になるので、第二画面にはimport Foundationを最初に書いておく。
・画面間のデータの受け渡しはoverride func prepareForSegue(・・・を用いる(第1画面)。
・べき乗はpow(a,b)で計算する。
・テキスト型の値を小数に変換するには a = (text! as NSString).doubleValueコードを用いる。
・異なる型が同一式の中に混在するとエラーになるので、注意する。
nilの入力を防ぐために第1画面のテキストフィールドには値を入れておき消去記号が出るように設定する。
・キーボードは数値用を設定。
=========================
(備忘録)数値の扱い
コード:Xcode7.1.1 Swift2
___________________________________________________
第1画面
_________________________
//
// ViewController.swift
// 体脂肪率計算アプリ:第1画面
//
// Created by yasui_swift on 2015/12/10.
// Copyright © 2015年 darumammz.com. All rights reserved.
//
import UIKit
class ViewController: UIViewController {

@IBOutlet weak var textHeight: UITextField!
@IBOutlet weak var textBW: UITextField!
@IBOutlet weak var textArm: UITextField!
@IBOutlet weak var textScarp: UITextField!
@IBOutlet weak var textAbd: UITextField!

override func viewDidLoad() {
super.viewDidLoad()
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let viewController2 = segue.destinationViewController as! secondViewController

/*secondViewCntrollerに受け継がれるitem
var text2Height:String?
var text2BW:String?
var text2Arm:String?
var text2Scarp:String?
var text2Abd:String?
*/

viewController2.text2Height = textHeight.text
viewController2.text2BW = textBW.text
viewController2.text2Arm = textArm.text
viewController2.text2Scarp = textScarp.text
viewController2.text2Abd = textAbd.text
}

@IBAction func returnTop(segue:UIStoryboardSegue){
}
}
_________________________
第2画面
_________________________
//
// secondViewController.swift
// 体脂肪率計算アプリ 画面2
//
// Created by yasui_swift on 2015/12/10.
// Copyright © 2015年 darumammz.com. All rights reserved.
//
import UIKit
import Foundation
class secondViewController: UIViewController {

// 受け継ぐ項目
var text2Height:String?
var text2BW:String?
var text2Arm:String?
var text2Scarp:String?
var text2Abd:String?

//画面2で計算する項目
var myBSA:Double = 1.80
var myHeight:Double = 171.1
var myBW:Double = 64.2

var fat2:Double = 1.0
var fat3:Double = 1.0

var ArmFat:Double = 1.0
var ScarpFat:Double = 1.0
var AbdFat:Double = 1.0

var aa:Double = 1.00
var bb:Double = 1.00

// 画面2へのラベルの配置
@IBOutlet weak var label2Height: UILabel!
@IBOutlet weak var label2BW: UILabel!
@IBOutlet weak var labelBMI: UILabel!
@IBOutlet weak var labelFat2: UILabel!
@IBOutlet weak var labelFat3: UILabel!

override func viewDidLoad() {
super.viewDidLoad()

myHeight = (text2Height! as NSString).doubleValue
myBW = (text2BW! as NSString).doubleValue
ArmFat = (text2Arm! as NSString).doubleValue
ScarpFat = (text2Scarp! as NSString).doubleValue
AbdFat = (text2Abd! as NSString).doubleValue

fat2 = ArmFat + ScarpFat
fat3 = fat2 + AbdFat

aa = pow(myHeight, 0.725)
bb = pow(myBW,0.425)

//体表面積の計算
myBSA = 72.46 * aa * bb//平方センチ。
let myBSA100 = Int(myBSA/10)//小数点以下を調整するために整数に変換

myBSA = Double(myBSA100) / 1000//平方メートルに変換

//体脂肪率の計算の準備
let XX = fat2 * myBSA / myBW * 100//2点法
let XXX = fat3 * myBSA / myBW * 100//3点法
let YY = 1.0923 - 0.000514 * XX //2点法身体密度(長瀬・鈴木の式1963)
let YYY = 1.0935 - 0.000297 * XXX //3点法身体密度

//2点法による体脂肪率の計算
var taiSibouRitsu = (4.570/YY-4.142)*100//体脂肪率(ブロゼックの式1963
let taiSibouRitsuM = Int(taiSibouRitsu*100)//小数点以下の調整のための仮数
taiSibouRitsu = Double(taiSibouRitsuM)/100

//3点法による体脂肪率の計算
var taiSibouRitsu3 = (4.570/YYY-4.142)*100//体脂肪率(ブロゼックの式1963)
let taiSibouRitsu3M = Int(taiSibouRitsu3*100)//小数点以下の調整のための仮数
taiSibouRitsu3 = Double(taiSibouRitsu3M)/100

//BMIの小数の桁数の調整
var myBMI = myBW/myHeight/myHeight*100*100

let myBMIinteger = Int(myBMI*100)//仮数:整数型
let myBMI100:Double = Double(myBMIinteger)//仮数
myBMI = myBMI100/100//小数型

label2Height.text = text2Height
label2BW.text = text2BW
labelBMI.text = String(myBMI)
labelFat2.text = String(taiSibouRitsu)
labelFat3.text = String(taiSibouRitsu3)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
=========================

いつの間にか季節は冬になっている。
次は、複数の画面間でデータを共有する複雑な方法を学びたい。