LoginSignup
3
2

More than 1 year has passed since last update.

【Combine】複数の値をまとめて監視する

Posted at

はじめに

ログイン画面などで全ての情報が入力されていない場合、ログインボタンを押せなくする動きを再現してみました。
複数の値をまとめて監視する方法を使用することで簡潔に書けたので紹介します。

サンプルアプリ

Simulator Screen Recording - iPhone 14 - 2022-12-15 at 21.16.34.gif

実装

View

import SwiftUI

struct ContentView: View {
    @StateObject var viewModel = ViewModel()
    var body: some View {
        NavigationStack {
            List {
                Section {
                    TextField("氏名", text: $viewModel.name)
                    Stepper(value: $viewModel.age) {
                        Text("年齢: \(viewModel.age.description)")
                    }
                } header: {
                    Text("基本情報")
                }

                Section {
                    TextField("ユーザーネーム", text: $viewModel.username)
                    SecureField("パスワード", text: $viewModel.password)
                } header: {
                    Text("アカウント情報")
                }

                Section {
                    loginButton
                }
            }
            .listStyle(.insetGrouped)
            .navigationTitle("ログイン")
        }
    }

    private var loginButton: some View {
        Button {
        } label: {
            Text("ログイン")
                .font(.system(size: 20, weight: .black))
                .frame(maxWidth: .infinity, alignment: .center)
        }
        .disabled(viewModel.isEnableLoginButton)
    }
}

ViewModel

import Combine

final class ViewModel: ObservableObject {
    @Published var name: String = ""
    @Published var age: Int = 0
    @Published var username: String = ""
    @Published var password: String = ""

    @Published var isEnableLoginButton: Bool = false

    init() {
        $name.combineLatest($age, $username, $password)
            .map { $0 == "" || $1 == 0 || $2 == "" || $3 == "" }
            .assign(to: &$isEnableLoginButton)
    }
}

解説

以下のコードでname, age, username, passwordを監視する指示を行っています。

$name.combineLatest($age, $username, $password)

以下のコードでそれぞれの値に入力が行われたかを判定しています。

.map { $0 == "" || $1 == 0 || $2 == "" || $3 == "" }

$0にはnameの値
$1にはageの値
$2にはusernameの値
$3にはpasswordの値

以下のコードでmapの結果をisEnableLoginButtonに代入しています。

.assign(to: &$isEnableLoginButton)

おわり

便利ですね

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2