SwiftUIで行こう! 電卓を作ろ!-演算しましょ。
https://note.com/dngri/n/n00eb7baa824d
の続きです。数字が打てるようになったのでいよいよ演算していきます。
https://www.youtube.com/watch?v=gDEeILcSK_U
を参考に作っていきます。
struct UnarySymbols:View
について演算ができるように計算ができるように関数funcを作っていきます。
let symbols = ["π","√","±","="]
と宣言しているので、この記号がなんであるかによって動作を変えます。
func performOperation(_ symbol:String){
switch symbol {
case "π":
self.display = String(Double.pi)
default:
break
}
}
そしてButtonのactionの関数を入れます。
Button(mathSymbol,action:{
self.performOperation(mathSymbol)
})
これで、実行して"π"をいれると表示部に"π"と表示されます。
次に表示部に関係する部分のコードを整理します。ContentView.swiftファイルのstruct ContentView: View{} の上に書いていきます。
class CalcViewModel:ObservableObject{
@Published var display = "0"
@Published var middleTyping = false
}
表示するデータ、打ち始めを決めていくデータを格納する変数を持ちます。ここでこのclassは階層を超えて使うことになるclassということで、
プロトコルは
ObservableObject
変数には
@Published
をつけます。そしてもう一つ作業があります。
class SceneDelegate{}
にコードを追加していきます。
var window: UIWindow?
var calculatorViewModel = CalcViewModel()
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
let contentView = ContentView().environmentObject(CalcViewModel())
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: contentView)
self.window = window
window.makeKeyAndVisible()
}
}
大事なところは、先ほど作ったクラスをenvironmentObjectとして登録します。
let contentView = ContentView().environmentObject(CalcViewModel())
これが終われば、
displayと middleTypingを最初に書いたものと入れ替えていきます。
それぞれの構造体structに
@EnvironmentObject var calcVM: CalcViewModel
を追加し、display、middleTypingとしていたと calcVM.display、calcVM.middleTypingとしていきます。
ここで気をつけないといけないのが、ContentView: View{}で読み込む構造体structを
HStack{
UnarySymbols()
Digits()
にしておかないとエラーがでます。
演算子をもう一つ追加しましょう
func performOperation{}
に"case"を追加します。ルートです。
case "√":
let operand = Double(calcVM.display)!
calcVM.display = String(String(sqrt(operand)))
self.calcVM.middleTyping = false
そして
calcVM.display = String(String(sqrt(operand)))
の部分をスッキリさせましょう。Computed Propertieを使います。変数に自動的に何か処理をさせることができます。
https://note.com/dngri/n/n5718cee6df68?magazine_key=m39ffd3b6c431
class CalcViewModel{}の中で使います。
var displayValue:Double{
get{
return Double(display)!
}
set{
display = String(newValue)
}
}
今あるデータ(get)を文字列から数字にする。もうひとつ、受け取ったデータ(数字)を文字列にします。
組み込みます。
func performOperation(_ symbol:String){
switch symbol {
case "π":
calcVM.displayValue = Double.pi
self.calcVM.middleTyping = false
case "√":
calcVM.displayValue = sqrt(calcVM.displayValue)
self.calcVM.middleTyping = false
default:
break
}
}
case "π"の場合、文字列から数字へ変換して"self.display"に入れています。
self.display = String(Double.pi)
から
calcVM.displayValue = Double.pi
としています。これは、"calcVM.displayValue"自体がデータを受け取った場合に数字にする機能があるため、"String()"の必要がなくなったということです。
calcVM.displayValue = sqrt(calcVM.displayValue)
の場合は文字列のデータを受け取り
変数display に入った時点で → displayValueで数字に変換。
それを平方根(sqrt)
sqrt(calcVM.displayValue)
してさらに文字列にしています。
コードもスッキリしてみやすくなりました。
実行するとこんな感じで演算子"π"と"√"、が使えるようになりました。
この記事が気に入ったらサポートをしてみませんか?