【SwiftUI】CheckBoxを使う(ToggleStyle)

SwiftUI

まず初めにSwiftUIにはCheckBoxそのものはありません。
しかしToggleを使ってCheckBoxにする事ができます。

ToggleStyleのmakebodyのドキュメントの例としても載っています。

makeBody(configuration:) | Apple Developer Documentation
Creates a view that represents the body of a toggle.

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としてまとめてしまえば手間は然程変わらず、
余分な知識も不要なのでこちらにも利点はあると思います。

コメント

タイトルとURLをコピーしました