【SwiftUI/iOS】Stepperの実装(カウンタのようなもの)

目次

概要

時にボタンで数の調整をしたくなる時がある。
ポケモンのゲームなどでもモンスターボールやきずぐすりを買う時、何個まとめて買うかを選択する時があるだろう。
今回はその数字の部分の実装を行う。
スマホなら、設定次第で少数も設定できる。

ソースコード

import SwiftUI

@main
struct TestApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    
    var body: some Scene {
        WindowGroup {
            StepperView()
        }
    }
}
import Foundation

class StepperViewModel: ObservableObject {
    @Published var bodyWeight: CGFloat = 60.0
    @Published var bodyHeight: CGFloat = 160.0
    @Published var bmi: CGFloat = 0.0
    
    func calcBmi() {
        bmi = bodyWeight / ((bodyHeight / 100) * (bodyHeight / 100))
    }
}
import SwiftUI

struct StepperView: View {
    @ObservedObject private var viewModel = StepperViewModel()
    
    var body: some View {
        VStack {
            HStack {
                Spacer()
                Text("体重")
                Stepper(value: $viewModel.bodyWeight, step: 0.1) {
                    Text("\(viewModel.bodyWeight, specifier: "%.1f") kg")
                }
                Spacer()
            }
            HStack {
                Spacer()
                Text("身長")
                Stepper(value: $viewModel.bodyHeight, step: 0.1) {
                    Text("\(viewModel.bodyHeight, specifier: "%.1f") cm")
                }
                Spacer()
            }
            HStack {
                Text("BMI: \(viewModel.bmi)")
            }
            Button {
                viewModel.calcBmi()
            } label: {
                Text("BMIを計算する")
            }
        }
    }
}

デモ動画

詳細

Stepperのプロパティは以下のような役割がある。

プロパティ名内容
step+/ーボタンを押下した時の刻み幅
value値を格納する変数
label表示されるUI

以下を例に取ってみよう。

Stepper(value: $viewModel.bodyHeight, step: 0.1) {
    Text("\(viewModel.bodyHeight, specifier: "%.1f") cm")
}

この場合、値が体重を示す変数で、刻み幅は0.1、labelはTextの部分(中括弧内)だ。

意外と単純に実装できた。

参考ページ