【SwiftUI完全初心者向け】@Stateを簡単に学ぼう

## はじめに

はじめまして！
bravesoft株式会社で今年の3月からインターンとしてエンジニアの卵として働いている山口と申します。
会社では入社時からさまざまな経験をさせていただいており、実務案件だけでなく、今回アドベントカレンダーの記事執筆にも挑戦させていただくことになりました！

**なおこの記事は私にとって初めての執筆経験ですので、温かい目で見守っていただければ幸いです:blush:**

## 今回作るもの
今回は、簡単に@Stateを学ぶために「カラーピッカー」アプリを作っていこうと思います。
カラーピッカーアプリを選んだ理由としては下記の5つが挙げられます。

- **簡単でわかりやすい:**
SwiftUIの基本的な要素（@State、Viewのレイアウト、Sliderの使い方など）を含んでおり、@StateだけでなくSwiftUIの基礎を学ぶのに最適です。

- **即時フィードバック:**
スライダーを動かすと色が即座に変わり、操作に対する結果がリアルタイムで確認できます。これにより、学習の楽しさが増します。

- **応用が効く:**
基本的な機能を構築した後、さらに色の保存機能や共有機能を追加して発展させられます。

- **興味を引きやすい:**
カラーピッカーは視覚的に魅力があり、モチベーションを維持しやすいテーマです。

- **実用性:**
@Stateは、値の更新を監視し、変更があれば自動でViewを再描画してくれる便利なプロパティです。

SwiftUIでは、通常、構造体内でプロパティを変更することができません。しかし、@Stateを使うことで、構造体内でも状態を管理し、動的に更新できます。

例えば、ボタンを押したりスライダーを動かしたりすると、@Stateの値が変わり、それに応じてビューが更新されます。

## 早速アプリを作っていこう！
iOS 14以降では、ColorPickerという組み込みのコンポーネントが提供されています。しかし今回は、あえて一からコードを書いてカラーピッカーを実装してみましょう。

完成のイメージはこちらです。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943896/d1af740e-2af3-c200-53a1-802a19cc2dbd.png" alt="ColorPicker" width="300">

### 完成コード
```swift
import SwiftUI

struct ContentView: View {
    @State private var red: Double = 0.5
    @State private var green: Double = 0.5
    @State private var blue: Double = 0.5
    
    var body: some View {
        VStack {
            Rectangle()
                .fill(Color(red: red, green: green, blue: blue))
                .frame(height: 200)
                .padding()

            redColorSlider
            greenColorSlider
            blueColorSlider
        }
    }
    
    private var redColorSlider: some View {
        HStack {
            Text("Red")
            Slider(value: $red, in: 0...1)
                .accentColor(.red)
        }.padding()
    }

    private var greenColorSlider: some View {
        HStack {
            Text("Green")
            Slider(value: $green, in: 0...1)
                .accentColor(.green)
        }.padding()
    }

    private var blueColorSlider: some View {
        HStack {
            Text("Blue")
            Slider(value: $blue, in: 0...1)
                .accentColor(.blue)
        }.padding()
    }
}

#Preview {
    ContentView()
}
```
**こちらで一旦コードを書くことができました！
上から順番にコードについての説明をしていきましょう。**
### 1. インポートと構造体定義
```swift
import SwiftUI

struct ContentView: View {
    @State private var red: Double = 0.5
    @State private var green: Double = 0.5
    @State private var blue: Double = 0.5
}
```
**import SwiftUI:**
SwiftUIフレームワークをインポートします。このフレームワークは、宣言的なUI構築をサポートするiOSアプリ開発の基本となるツールです。

**struct ContentView: View:**
ContentViewという名前の構造体を定義し、Viewプロトコルに準拠します。これがアプリの画面を構築する基本単位となります

**@Stateプロパティ:**
red、green、blueの各変数を@Stateとして定義します。この修飾子により、ビューの状態を保持し、状態が変化するとビューが自動的に再描画されます。ここでは初期値をそれぞれ0.5に設定しています。

### 2. bodyプロパティ
```swift
var body: some View {
    VStack {
        Rectangle()
            .fill(Color(red: red, green: green, blue: blue))
            .frame(height: 200)
            .padding()

        redColorSlider
        greenColorSlider
        blueColorSlider
    }
}
```
**var body: some View:**
ビューの描画内容を定義するプロパティです。このプロパティは必ず一つのビューを返す必要があります。

**VStack:**
内部のビューを縦に配置するため、使用します。

**Rectangle:**
四角形のビューを作成し、fillメソッドを使って現在のred、green、blueの値から生成される色で塗りつぶします。
- frame(height: 200)で高さ200ポイントの四角形を指定
- padding()で周囲に余白を追加

**redPicker, greenPicker, bluePicker:**
後ほど定義される各カラースライダーのビューをここで配置します。

### 3. プライベートカラーピッカービュー
```swift
private var redColorSlider: some View {
    HStack {
        Text("Red")
        Slider(value: $red, in: 0...1)
            .accentColor(.red)
    }.padding()
}

private var greenColorSlider: some View {
    HStack {
        Text("Green")
        Slider(value: $green, in: 0...1)
            .accentColor(.green)
    }.padding()
}

private var blueColorSlider: some View {
    HStack {
        Text("Blue")
        Slider(value: $blue, in: 0...1)
            .accentColor(.blue)
    }.padding()
}
```
**private var redColorSlider: some View（greenColorSlider, blueColorSlider）:**
各カラースライダーを定義するプライベート変数です。スライダーごとに共通する部分を分けることで、コードが整理されます。

**HStack:**
テキストとスライダーを横並びに配置するため、使用します。

**Text("Red")（および他の色）:**
各スライダーのラベルを表示します。

**Slider(value: $red, in: 0...1):**
スライダーコンポーネントを使用します。
- value: $redのように、@Stateで定義された変数とデータバインディングすることで、スライダーの値を状態として管理します
- in: 0...1でスライダーの範囲を指定
- accentColor(.red)でスライダーの色を設定

**.padding():**
各スライダーに余白を追加して見た目を整えます。

**これでユーザーが各色成分（赤、緑、青）をスライダーで調整し、リアルタイムでその結果を四角形の色で表示するカラーピッカーアプリが完成しました！:star2:**


### まとめ
この記事を通して、SwiftUIの基本的な機能である@Stateを使ったカラーピッカーアプリを作成しました。シンプルながらも即時フィードバックが得られるこのアプリを通じて、SwiftUIの強力な宣言的プログラミングモデルの魅力を感じていただけたと思います。

このアプリを発展させるアイデアとしては、以下のようなものがあります：
- 選択した色の16進数コードを表示する機能
- 現在の色を他のアプリで共有する機能
- 色を保存して再利用できるようにする機能

小さな改良を積み重ねることで、このアプリがさらに実用的で楽しいものになるはずです！ぜひ皆さんも挑戦してみてください。

## 最後に
この記事が少しでも役に立ったり、SwiftUIの学習の助けになったりすれば嬉しいです。
初めての記事執筆で至らない点もあるかと思いますが、最後まで読んでいただき、ありがとうございました！今後も引き続きより良いコンテンツを発信していけるよう努力します！:smile: