TextFieldの値とSliderのバーを同期させる方法
自作のBinding
import SwiftUI
struct SliderTextFieldSyncView: View {
@State private var value: Double = 50.0 // 共通の状態
var body: some View {
VStack(spacing: 20) {
Slider(value: $value, in: 0...1000, step: 1)
// TextFieldではDoubleをStringに変換して表示・編集
TextField("数値を入力", text: Binding(
get: {
String(format: "%.0f", value)
},
set: { newValue in
if let doubleValue = Double(newValue) {
value = min(max(doubleValue, 0), 1000) // 範囲外防止
}
else {
// 無効な入力に対する対応(例:無視、前の値に戻す、警告表示など)
}
}
))
.keyboardType(.numberPad)
.textFieldStyle(RoundedBorderTextFieldStyle())
.frame(width: 100)
}
.padding()
}
}
#Preview {
SliderTextFieldSyncView()
}
SwiftUIのTextFieldはBinding<String>を受け取る。一方で、Sliderで扱う値はDouble型になります。したがって、そのまま$valueを渡すことができないため、Double←→Stringの変換を含む、カスタムバインディングを作成する必要がある。
Binding(
get: {
String(format: "%.0f", value)
},
set: { newValue in
if let doubleValue = Double(newValue) {
value = min(max(doubleValue, 0), 1000)
}
}
)
getに表示するときの処理を書き、setに入力する際の処理を記述します。

NumberFormatterを利用
import SwiftUI
struct SliderTextFieldSyncView: View {
@State private var value: Double = 50.0
// NumberFormatterを定義(ローカライズ対応)
private var numberFormatter: NumberFormatter {
let formatter = NumberFormatter()
formatter.numberStyle = .decimal // 桁区切りや小数点をローカル形式で表示
formatter.maximumFractionDigits = 0 // 小数点以下を表示しない
formatter.minimum = 0
formatter.maximum = 1000
return formatter
}
var body: some View {
VStack(spacing: 20) {
Slider(value: $value, in: 0...1000, step: 1)
TextField("数値を入力", value: $value, formatter: numberFormatter)
.keyboardType(.numberPad)
.textFieldStyle(RoundedBorderTextFieldStyle())
.frame(width: 100)
}
.padding()
}
}
#Preview {
SliderTextFieldSyncView()
}

コメント