Storyboardで横スクロールを作成する手順（UIScrollView & UIStackView）

# 目的

XcodeのiOSアプリで、StoryboardのUIScrollViewとUIStackViewを使って横スクロール（またはウォークスルーみたいなもの）を簡単に作成する手順を紹介します。

# 記事を書いた理由

UIScrollViewが曲者すぎて檄ハマりしたので、備忘録＆共有として書きました。

# 完成形

<img width="200" alt="スクロール動作確認.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487144/e95140e3-8d21-da29-9d13-7c1b7fd63001.gif">

# 環境

| 対象 | バージョン |
| --- | --- |
| Xcode | 12.2 (12B45b) |
| Swift | 5 |

今回の作成環境が上記なだけで、多少前後しても問題ないと思います。

# 目次

1. 準備
2. UIScrollViewを追加
3. UIStackViewを追加
4. スクロール対象のObjectを追加
5. 動作確認

# 手順

## 1. 準備

XcodeでStoryboardとViewControllerを用意してください。
※今回はNewProjectの初期状態から始めます

![スクリーンショット 2020-12-19 18.46.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487144/4be74bc3-87f3-bdda-48e8-0b714f3116a3.png)

## 2. UIScrollViewを追加

### Objectの選択

Object LibraryからUIScrollViewを選択してStoryboardに追加します。

![Objectの追加.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487144/47155913-e700-0937-ecbb-ce43c1ce5102.png)
![UIScrollViewの選択.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487144/3debda53-cc6a-2062-fbcd-43cda198ab28.png)
![UISCrollViewの配置.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487144/9e2f36f8-b5b2-0135-9be3-0efa72444e66.png)

### 配置調整

AutoLayoutなどを使用して任意の配置を行ってください。
今回はセーフエリア内に最大表示するように配置してみます。

![UIScrollViewの配置制約.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487144/5baa630b-46f2-3578-5cab-6129d591b9cc.png)
![UIScrollViewの配置制約後.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487144/727f06eb-0909-32fc-bbca-4ea9ef527269.png)

AutoLayoutすると赤くエラー表示が出ます。
「ちゃんといつも通り制約指定したじゃん！」と思うはずです。
後で直るので一旦このエラーはほっときましょう。

### UIScrollViewの設定を変更

UIStackViewを追加する前にUIScrollViewの設定を変更しておきましょう。
右メニューのSize inspectorを開いて、Content Layout Guidesのチェックボックスを解除（falseに設定）しましょう。

![UIScrollViewのContent Layout Guides.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487144/3d598bc8-3379-2261-4077-af149b9ada3e.png)
![ UIScrollViewのエラーが直る.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487144/773e931e-6e97-286b-f096-3ec2a7d47263.png)

この状態でUIScrollViewの配置制約のエラーが直ると思います。

※配下にViewを追加するとまたエラーになります
　理由はUIScrollViewのサイズが配下（内部）に配置したViewのサイズに依存するからです
　このサイズはUIScrollViewのContentSizeとして認識される値です
　最終的に配下のViewのサイズを指定するのでエラーは直ります

## 3. UIStackViewを追加

### Objectの選択

Object LibraryからUIStackViewを選択してStoryboardに追加します。
今回は横スクロールなのでHorizontal Stack Viewを使用します。
UIScrollViewの配下に配置してください。

![Objectの追加.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487144/47155913-e700-0937-ecbb-ce43c1ce5102.png)
![UIStackViewの選択.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487144/0c9f1058-6234-db22-b171-a1a5f0c2fd60.png)
![UIStackViewの配置.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487144/34fae205-c076-6317-7dc0-29a11153f0a6.png)

### 配置調整

AutoLayoutなどを使用して任意の配置を行ってください。
今回はAutoLayoutを使ってUIScrollView内で最大表示するように設定します。

高さをUIScrollViewと同じ高さになるように制約を設定します。
これをやらないとエラーになります。

![UIScrollViewとUIStackViewの高さを同じに制約.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487144/1143a5ba-667c-aff6-6df6-1c0fe956671a.png)
![UIStackViewの配置制約.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487144/554b7d10-d9ec-3f35-c9d4-878e0fc3d1ee.png)
![UIStackViewの配置制約後.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487144/2e8c60d7-aeed-7818-b233-7069db7c6a40.png)

配置制約がエラーになっていますが、中のコンテンツを追加すれば直るので一旦ほっときましょう。

## 4. スクロール対象のObjectを追加

### Objectの選択

スクロールする対象のObjectを追加していきます。
今回は分かりやすく背景色付きのUIViewにしますが、目的に合わせて任意のObjectにしてください。
数も今回は3つにしますが、任意の数にしてください。

![スクロール対象のObjectを配置.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487144/80f0a66d-96e3-6406-8461-ef1a82c6b7a0.png)

### 配置調整

今回は高さをAutoLayout、幅を一番大元のUIViewと一致するように制約をかけます。
「幅を一番大元のUIViewと一致させる」部分が重要です。
ここはAutoLayoutだと上手く制約が効きません。
なお、上記のやり方はスクロールの一ページあたりが画面の横幅と等しくする場合の手順ですので、それ以外の場合は固定値を指定するのでも問題ありません。

![スクロール対象の一つ目に制約を設定する手順.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487144/b859a5c0-eed1-de51-d996-f3a86eab1d40.png)
![スクロール対象の一つ目に制約を設定後.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487144/8cf04f86-d71f-4bcd-58e2-ae2e745fbb89.png)
![スクロール対象の二つ目に制約を設定する手順.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487144/6a9488e9-115b-f385-5a48-eb2fe59b5cc7.png)
![スクロール対象の二つ目に制約を設定後.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487144/a4edae11-f064-c7d1-1a05-5bbf32d36a74.png)
![スクロール対象の三つ目に制約を設定する手順.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487144/9aa83634-fbf2-23ee-7f98-1c4467b20e67.png)
![スクロール対象の三つ目に制約を設定後.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487144/bc494d41-e5ba-fa70-2545-3d7a57e7e3a1.png)

これで全ての設定が完了しました！
配置制約に関するエラーが全て無くなったと思います。

## 5. 動作確認

### コンテンツのUIViewの違いを分かるようにする

本来は異なるコンテンツを並べると思うのでこの手順は不要です。
今回は全てまっさらなUIViewなので、違いがわかるように背景色を設定しておきます。
今回は赤・黄・緑に分けてみました。

![スクリーンショット 2020-12-19 20.14.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487144/fe37f732-1485-c656-8859-dca7d67cea56.png)
![スクリーンショット 2020-12-19 20.14.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487144/4d71c858-0722-d25a-a9f1-b8205ad0f7fd.png)
![スクリーンショット 2020-12-19 20.14.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487144/eb13214f-c6c9-07ea-36d5-d686f6e376a1.png)

### 動かしてみる

ビルドしてエミュレーターを起動します。
下記の通りスワイプして横スライドが出来ていれば成功です！

<img width="200" alt="スクロール動作確認.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487144/e95140e3-8d21-da29-9d13-7c1b7fd63001.gif">

# おまけ

UIScrollViewを選択した状態で、右メニューのAttributes inspectorからスクロールの挙動をある程度指定できます。

- 縦スクロールバーの表示有無
- 横スクロールバーの表示有無
- スクロール可否
- ページ単位でのスクロール可否（trueにすると一画面分ずつ切り替わります）
- スクロール時のバウンス可否
- ズーム時のバウンス可否
- 縦スクロール時のバウンス可否
- 横スクロール時のバウンス可否

など...

![Attributes inspector.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487144/50421cd3-4854-276f-60fc-d0a9adcf44e7.png)