【SwiftUI】ステッパーの使用方法

こんにちはコーヤです。

このページでは、SwiftUIのステッパーの使用方法についてご紹介します。

以下のバージョンで動作確認しています。

  • Xcode 13.4.1
  • Swift 5.6.1

ステッパーのコード

Stepper(value: 値) {
    Text(テキスト)
}
struct ContentView: View {
    @State var count: Int = 0
    var body: some View {
        VStack(spacing: 20) {
            Text("\(count)")
            Stepper(value: $count) {
                Text("Count")
            }
            .fixedSize()
        }
        .font(.largeTitle)
    }
}

ステップ範囲の設定方法

Stepper(value: 値, in: ステップ範囲)

下記のコードではステップ範囲を0から10までに設定しています。10になるとこれ以上増加できないため+ボタンがグレーアウトします。

struct ContentView: View {
    @State var count: Int = 0
    var body: some View {
        VStack(spacing: 20) {
            Text("\(count)")
            Stepper(value: $count, in: 0...10) {
                Text("Count")
            }
            .fixedSize()
        }
        .font(.largeTitle)
    }
}

ステップ間隔の設定方法

Stepper(value: 値, step: ステップ間隔)

下記のコードではステップ間隔を2にしているので、1回の操作で値が2ずつ増減します。

struct ContentView: View {
    @State var count: Int = 0
    var body: some View {
        VStack(spacing: 20) {
            Text("\(count)")
            Stepper(value: $count, step: 2) {
                Text("Count")
            }
            .fixedSize()
        }
        .font(.largeTitle)
    }
}

ステッパー操作中の判定方法

Stepper(value: 値, onEditingChanged: { bool in
    フラグ = bool
})

ステッパー操作中かどうかを判定することができます。

増減のボタンで操作されている間はフラグがtrueになり、ボタンが操作されていない間はfalseになります。

struct ContentView: View {
    @State var count: Int = 0
    @State var isEditing: Bool = false
    var body: some View {
        VStack(spacing: 20) {
            Text("\(count)")
            Stepper(value: $count, onEditingChanged: { bool in
                self.isEditing = bool
            }) {
                Text("Count")
            }
            .fixedSize()
            if isEditing {
                Text("Editing")
            } else {
                Text("No Editing")
            }
        }
        .font(.largeTitle)
    }
}

増減ごとの処理の設定方法

Stepper(onIncrement: {
    増加時の処理
}, onDecrement: {
    減少時の処理
})

増加時と減少時で別々の処理を設定することができます。

下記のコードは5ずつ増加し1ずつ減少するステッパーです。

logには増減どちらの操作をしたかを格納し、テキストで表示しています。

struct ContentView: View {
    @State var count: Int = 0
    @State var log: String = "null"
    var body: some View {
        VStack(spacing: 20) {
            Text("\(count)")
            Stepper(onIncrement: {
                self.count += 5
                log = "increased"
            }, onDecrement: {
                self.count -= 1
                log = "decreased"
            }) {
                Text("Count")
            }
            .fixedSize()
            Text(log)
        }
        .font(.largeTitle)
    }
}

ステッパーとテキストの間隔

.fixedSize()

fixedSizeのモディファイアを使用すると、ステッパーとテキストが隣接します。

モディファイアを使用しないと、テキストが左端、ステッパーが右端に配置されます。

struct ContentView: View {
    @State var countA: Int = 0
    @State var countB: Int = 0
    @State var countC: Int = 0
    var body: some View {
        List {
            Section(header: Text("with fixedSize").font(.title)) {
                Stepper(value: $countA) {
                    Text("StepperA")
                }
                .fixedSize()
                Stepper(value: $countB) {
                    Text("StepperB")
                }
                .fixedSize()
                Stepper(value: $countC) {
                    Text("StepperC")
                }
                .fixedSize()
            }
            Section(header: Text("without fixedSize").font(.title)) {
                Stepper(value: $countA) {
                    Text("StepperA")
                }
                Stepper(value: $countB) {
                    Text("StepperB")
                }
                Stepper(value: $countC) {
                    Text("StepperC")
                }
            }
        }
    }
}

ラベルの非表示設定

.labelsHidden()
struct ContentView: View {
    @State var count: Int = 0
    var body: some View {
        HStack {
            Spacer()
            VStack(spacing: 20) {
                Text("\(count)")
                Stepper(value: $count) {
                    Text("Count")
                }
                .fixedSize()
            }
            Spacer()
            VStack(spacing: 20) {
                Text("\(count)")
                Stepper(value: $count) {
                    Text("Count")
                }
                .fixedSize()
                .labelsHidden()
            }
            Spacer()
        }
        .font(.largeTitle)
    }
}

以上です。ご参考になれば幸いです。

コメント欄