久々にiOSアプリを作りたくなってSwiftUIを試してみた (レイアウト編)

## これはなに
最近、叔父とApple Storeに行く機会があったのですが、そこで大量のiPhoneを目の当たりにした時に、ふとiOSアプリを作りたくなったので、その過程をまとめました。

ちなみに、私は6年前くらい前にiOSアプリ開発をしており、その際にはStoryboardを用いて作成していました。
最近はSwiftUIというものが主流らしいので、今回はSwiftUIを使用して、よく題材になるタスク管理系のアプリを作ってみようと思います。


## StoryboardとSwiftUIの違い

- Storyboard
    - ボタンやラベルなどのオブジェクトをドラッグ&ドロップで配置して画面レイアウトを作っていく手法
- SwiftUI
    - 2019年頃から登場し、画面のレイアウトは全てコードで実装するという手法

色々と調べてみると、現在はSwiftUIが主流で今からアプリを作る場合には、ほとんどStoryboardは使われないとのこと。

(昔はStoryboard内の要素が増えていくとXcodeが重くなりがちっていうのと、GUIが故にコンフリクトした際に修正が難しいみたいな課題はありました。)

## プロジェクトの作成

StoryboardとSwiftUIどちらも、MacでXcodeというツールを使って開発を行います。
(Xcodeは App Storeから DLできます)

Xcodeを開いたら、新しいプロジェクトを作成して、iOSアプリ選択。

![スクリーンショット 2023-11-29 11.07.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2322481/06c46fa1-701f-0186-564d-bd40f6b9acd8.png)

InterfaceをSwiftUIに設定します。

![スクリーンショット 2023-11-29 11.08.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2322481/e2388872-d4af-d7f9-af99-8cb14e958dc9.png)

作成が完了すると以下の画面になると思います。
(右側のプレビューが立ち上がっていない場合は、右上の`resume`を押すと立ち上がります)

![スクリーンショット 2023-11-29 11.12.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2322481/e05b921d-9fe2-21bf-a09a-e3942d297f7d.png)


## レイアウト作成

基本的に、レイアウトはbodyの中に書いていきます。

```swift
struct ContentView: View {
    var body: some View {
        // ここにレイアウト用のコードを追加していく
    }
}

// 右のプレビューに表示するためのコードで、今回は触らない。
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
```

### 大枠を NavigationView / List / Text を用いて作ります
基本的に、親要素の `{}` の中に 子要素を入れていくようなイメージです。
HTMLを触ったことがある方であれば、そこまで違和感ないかと思います。

```swift
struct ContentView: View {
    var body: some View {
        NavigationView {
            List {
                Text("タスク1")
                Text("タスク2")
                Text("タスク2")
            }
            .navigationTitle("タスクアプリ")
        }
    }
}
```

- **NavigationView**
    - 階層的なページに対して簡単に画面遷移を実装するために使用
    - ページのタイトルなども設定可能
    - 最新のOSでは非推奨となっているため、その場合は NavigationStackを使用してください。

- **List**
    - iPhoneの設定画面等でもよく見るリスト要素。色々なアプリで利用されています。

- **Text**
    - 文字を表示するために使用します。

※細かい設定などは、公式リファレンスを参照してください。


<img width="200" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2322481/262dc886-71f1-dc10-47f2-e71a4b51539e.png">


### 達成状況を HStack / Image を用いて追加します。 

```swift
struct ContentView: View {
    var body: some View {
        NavigationView {
            List {
                HStack {
                    Image(systemName: "circle")
                    Text("タスク1")
                }
                HStack {
                    Image(systemName: "circle")
                    Text("タスク2")
                }
                HStack {
                    Image(systemName: "circle")
                    Text("タスク3")
                }
            }
            .navigationTitle("タスクアプリ")
        }
    }
}
```

- **HStack**
    - HはHorizontalの略で、横に要素を並べるために使用
        - 他にもStackの種類として下記があります
            - VStack
                - 縦に要素を並べるために使用
            - ZStack
                - Z軸方向、要素を重練るために使用
- **Image**
    - 画像を表示するために使用します。
    - systemName を指定することでシステムにあらかじめ入っている画像を使用することができます。
        - 名前はこちらを参照: https://developer.apple.com/sf-symbols/


<img width="200" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2322481/97a37294-4bcf-2963-d46c-e56e2e1bd59e.png">


## まとめ(感想)
タスクの追加・削除・完了 などの動作はまだできていませんが、ざっくりとした見た目はこれで完了です。

思ったよりも少ないコード量でかつ直感的にレイアウトが組めた気がします。
またビルドの必要もなく、ほぼリアルタイムでのプレビューができ待ち時間が少ないのもありがたかったです。

おそらく Storyboard であれば、作業量及び動作確認に数倍以上かかっていた気がします。


iOSアプリ開発って聞くとなんだか難しそうな印象を抱く人も多そうに思いますが、HTML触ったことがあればおそらく誰でも簡単にレイアウトを組むことはできそうなので、興味をお持ちの方はとりあえず作ってみるのが良さそうに思いました！
(今回紹介した要素の組み合わせだけでも色々なレイアウトが組めると思います)


>タスクの追加・削除・完了 などの動作はまだできていません

このあたりも調べつつ、また次回の記事で紹介できるようにします！