【SwiftUI】Toggleの使い方を徹底解説~色変更、Labelを非表示、タップ判定、スタイル自作~

この記事では、Toggleの実装方法について徹底解説していきたいと思います。

Toggleとは?

SwiftUIのToggleというのは、UIKitで言うSwitchのことです。ON/OFFを切り替えられるアレです。

タップすると切り替わります。(よくスワイプする人がいますが意味ないです)

緑色がONの状態で、グレーがOFFの状態です。

実装方法は簡単で、@StateのBool型を宣言して、Toggle("Toggle", isOn: $flag)だけで実装できます。

Toggleのスタイル

シンプル

struct ContentView: View {
    @State private var flag = true
    
    var body: some View {
        Toggle("Toggle", isOn: $flag)
            .padding()
    }
}

文字なし

struct ContentView: View {
    @State private var flag = true
    
    var body: some View {
        Toggle("", isOn: $flag)
            .labelsHidden()
    }
}

文字なし(ただ空にするだけ)

struct ContentView: View {
    @State private var flag = true
    
    var body: some View {
        Toggle("", isOn: $flag)
            .padding()
    }
}

文字あり(値を使う場合)

struct ContentView: View {
    @State private var flag = true
    
    var body: some View {
        Toggle(isOn: $flag) {
            Text(flag ? "ON" : "OFF")
        }
        .padding()
    }
}

ボタンスタイルのToggle

struct ContentView: View {
    @State private var flag = true
    
    var body: some View {
        Toggle(isOn: $flag) {
            Text(flag ? "ON" : "OFF")
        }
        .toggleStyle(.button)
        .padding()
    }
}

.buttonスタイルの装飾

struct ContentView: View {
    @State private var flag = true
    
    var body: some View {
        VStack {
            Toggle("大きいボタン", isOn: $flag)
                .toggleStyle(.button)
                .controlSize(.large)
                .padding()
            Toggle("赤色のボタン", isOn: $flag)
                .toggleStyle(.button)
                .tint(.red)
                .padding()
        }
    }
}

ちなみに、デフォルトは.toggleStyle(.switch)です。

Toggleの色を変える

struct ContentView: View {
    @State private var flag = false
    
    var body: some View {
        Toggle("Toggle", isOn: $flag)
            .toggleStyle(SwitchToggleStyle(tint: .red))
            .padding()
    }
}

.tint(.red)でもOKです。

スタイルを自作する

struct ContentView: View {
    @State private var flag = false
    
    var body: some View {
        Toggle("Toggle", isOn: $flag)
            .toggleStyle(CheckBoxToggleStyle())
            .padding()
    }
}

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に対して、func makeBodyでToggleのスタイルを自作することができます。

struct MyToggleStyle: ToggleStyle {
    func makeBody(configuration: Configuration) -> some View {
        // ここにToggleのデザインを記述する
    }
}

値変更時のイベント取得

.onChangeで値が変わったときのイベントが取得できます。ここで値を保存したりしましょう。

struct ContentView: View {
    @State private var flag = true
    
    var body: some View {
        Toggle("Toggle", isOn: $flag)
            .padding()
            .onChange(of: flag) { newValue in
                print("値が変わったよ:\(newValue)")
            }
    }
}

値の初期値を変更する

flagの初期値を取得して、.onAppearで値を入れるだけです。

struct ContentView: View {
    @State private var flag = true
    
    var body: some View {
        Toggle("Toggle", isOn: $flag)
            .padding()
            .onAppear {
                flag = false
            }
    }
}