まず初めにSwiftUIにはCheckBoxそのものはありません。
しかしToggleを使ってCheckBoxにする事ができます。
ToggleStyleのmakebodyのドキュメントの例としても載っています。
SwiftUIではButtonのラベルを変えたり、onTapGestureでImageを変えるなども簡単に出来ますが、
SwiftUI的なコードで汎用的な使い方が出来るものになるのでToggleStyleの使い方も是非覚えて行って下さい。
Toggle
ToggleはBool値を切り替える事が出来るViewです。
@State var toggle = false
Toggle("Toggle", isOn: $toggle)
Toggle(isOn: $toggle){
Text("Toggle")
}
この様に@StateでマークしたBool型変数を渡すこと事で、
タップで切り替えが行われる様になります。
ラベルは簡易的にStringを渡す事も出来ますし、Viewを渡す事も出来ます。
ToggleStyle
見た目を変えたい場合はtoggleStyle Modifierを使うことが出来ます。
ToggleStyleはswitchとbuttonが用意されており、iOSでは標準(automatic)ではswitchとなります。
Toggle("Toggle", isOn: $toggle)
.toggleStyle(.button)
※上 .switch、下 .button
※本記事の画像は全て見やすい様にpaddingとborderを追加しています。
CheckBox
先にも言った通りCheck Boxは標準では用意されていません。
また、引数のLabelだけで行おうとしても上手くいきません。
そこで使うのがToggleStyleです。
ToggleStyle Protocolで好みの形に実装することが出来ます。
struct CheckBoxToggleStyle:ToggleStyle{
func makeBody(configuration: Configuration) -> some View {
Button{
configuration.isOn.toggle()
} label: {
HStack{
configuration.label
Spacer()
Image(systemName: configuration.isOn
? "checkmark.circle.fill"
: "circle")
}
}
}
}
ToggleStyleを実装しmakeBodyメソッドを実装します。
returnはsome ViewなのでViewのbodyの様にViewを実装すればOKです。
引数のconfigurationからisOnの値とlabelの値を取得出来るので、Viewで表示や変更を行いましょう。
今回はButtonでやっていますがonTapGestureなどアクションで切り替えができれば何でも大丈夫です。
Toggleに適用するときは以下の様にします。
Toggle("Toggle", isOn: $toggle)
.toggleStyle(CheckBoxToggleStyle())
toggleStyleに定義した構造体を渡すだけで後は同じですね。
この様に他のToggleと同じような書き方で適用することが出来、使い回しも簡単です。
Modifierを使うのでSwiftUIらしくなり見通しも良くなります。
折角なので他のToggleStyleと同じように使える様にしてみましょう。
extension ToggleStyle where Self == CheckBoxToggleStyle {
static var checkBox: CheckBoxToggleStyle {
get { CheckBoxToggleStyle() }
}
}
よくあるextensionの使い方の1つですね。
toggleStyle ModifierはToggleStyleが引数となっているので、
プロパティとしてCheckBoxToggleStyleを追加しました。
これで以下の様な使い方が出来ます。
Toggle("Toggle", isOn: $toggle)
.toggleStyle(.checkBox)
他の方法
単純にViewを組み合わせてCheckBoxにする方法です。
@State var check = false
HStack {
Text("CheckBox")
Spacer()
Button{
check.toggle()
} label: {
Image(systemName: check
? "checkmark.circle.fill"
: "circle")
}
}
HStack {
Text("CheckBox")
Spacer()
Image(systemName: check
? "checkmark.circle.fill"
: "circle")
.onTapGesture {
check.toggle()
}
}
要はToggleStyleで実装した中身を直接Viewとして使う形です。
これも1つのViewとしてまとめてしまえば手間は然程変わらず、
余分な知識も不要なのでこちらにも利点はあると思います。
コメント