Storyboardで作成したUIScrollViewが、スクロールバーは動くのにスクロールできない

投稿者: Anonymous

以下の記事を参考にして、UIScrollView内に、UIViewを配置してその中にコンテンツ(UILabel)を配置しました。

【UIScrollView】Autolayoutで縦スクロール【Xcode8.x】 – Qiita

しかし、以下のgif動画のように、右側のスクロールバーは動いているのに、中央に配置したLabel等が動かないという状態になってしまいます。

画像の説明をここに入力

1度だけなにかの拍子でうまく動かせたのですが、その後2時間くらい再現しようと色々試してもうまく行かなかったので質問させてください。

試した手順

①ViewControllerをfreedomに変更し、heightを2800へ
画像の説明をここに入力

②デフォルトで生成されているUIView内にUIScrollViewを配置
画像の説明をここに入力

③UIScrollViewに4つの制約を追加
画像の説明をここに入力

④UIScrollViewの中にUIView(ContentView)を追加
画像の説明をここに入力

⑤UIView(ContentView)に5つの制約を追加
画像の説明をここに入力

⑥UIView(ContentView)の中にUILabelを追加
画像の説明をここに入力
画像の説明をここに入力

何が原因だと考えられますでしょうか?

追記:私のXCode上でのConstraintは以下の画像のようになっていました。
画像の説明をここに入力

解決

まずは、参考にされている記事が古すぎます。iOSやSwift言語とともに、Xcodeの使い方もバージョン毎に変わっていっています。記事内には存在しない「Content Layout Guide」や「Frame Layout Guide」が、あなたのstoryboardには存在していることがわかるかと思います。

Xcode 11を使っているなら、Xcode 11用の記事を見つけて下さい。

現在ご質問中に含まれる情報だけではどのような制約をつけられたのかがわからないのですが、⑤の画像を見る限りContentViewに付けられた制約が間違っている可能性が高いです。

なお、storyboardの設定状態を画像で説明しようとする場合、Constraintsを展開した状態のものを示していただくと、より詳しい情報が伝わります。

スクロールが成功するときの制約の状態

あなたの現在の制約では、ContentViewのleading, trailing, top, bottomがFrame Layout Guideなんかに向けられていないでしょうか?

Frame Layout GuideはUIScrollViewそのものの画面上での表示範囲を表しています。上下左右をそれに固定する、と言うことはContentViewに「画面上の表示範囲から動くな」と言う制約をつけていることになります。

一旦それらの制約は全て削除して、(上の画像にあるように)Content Layout Guideに対する制約をつけて下さい。

Xcode 11におけるUIScrollViewでの制約の付け方については、次の記事(英語ですが)がわかりやすくまとまっていました。

How to use scroll view in Interface Builder / Storyboard (Xcode 11)

(残念ながら、私の検索技能では、日本語のわかりやすい記事は見つかりませんでした…。)


UIScrollViewを使った画面にうまく制約をつけて画面のレイアウトを行うのは、かなり難易度が高く、私はこれまでずっとUIScrollViewを直接使うのは避けてきたので、あまりうまく説明できませんが、何かわかりにくい点があれば、例によってコメントなどして下さい。

回答者: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *