2014年04月11日

iOS7 - スクロールとちょっとだけ Auto Layout (1)

前回 「 テキストフィールドとキーボード管理」では、簡単な入力フィールドとそれに伴うキーボードの使い方を取り上げました。
今回は、UIScrollView 表示コンテンツのスクロールと、iOS7/Xcode5 で格段に使いやすくなたAuto Layout のさわりを、ちょっとだけ、説明します。
両方とも、入力フィールドが画面に多数存在する画面になったときに、キーボードとの調整をにするには欠かせない機能です。

特に Auto Layout は、画面の解像度が多種になる今後を踏まえて、Xcode の Storyboard を使ってコードレスで取り組むのが主流になるでしょう。Auto Layout の詳細は、機会を改めて、ゆっくり説明したいと思っています。

スクロールビュー


UIScrollView の追加



それでは、前回のXcode プロジェクトを開いて、ストーリーボード(Main.storyboard)を選択します。
右下パネルのオブジェクトライブラリから「Scroll View」を選んで、メインビューにドラッグします(図1)
drag_scrollview.png
図1 UIScrollView の配置

縦横のサイズは後で調整しますので、いまは気にしないでください。
スクロールの対象となるコンテンツを格納するビューを、スクロールビュー内にドラッグして入れます。(図2)
前回使ったラベルとテキストフィールドはこのコンテンツビューの中に入れます(後述)。
drag_sc_contents.png
図2 コンテンツビューの配置

スクロールビューとコンテンツビューが、メインビューにぴったり収まるようにサイズを調整します。(図3)
sc_resize_hl.png
図3 スクロールビューのサイズ調整とビュー階層

図3のとおりラベルとテキストフィールドは階層の奥に隠れてしまいいました。
ドキュメントアウトラインの中のこれらのパーツを選択しコンテンツビューのサブビューになるように移動します。(図4)
move_fields_n_labels.png
図4 UIコントロールの移動

移動したら、コンテンツビューの中で、元のレイアウトと同じになるように再配置します。

シミュレータで実行すると、前回の投稿と何ら変わりのない状態で起動するはずです。
スクロールビューにしましたが、表示領域とコンテンツビューのサイズが同じなので、スクロールはできません。

コンテンツビューのサイズ変更


スクロールが可能になるようにコンテンツビューの高さを大きくします。コンテンツビューを選択して、右サイドパネルのサイズ・インスペクターをクリックします。サイズ・インスペクターの「Height」を増やします。(600以上目安)(図5)
resize_content_view.png
図5 コンテンツビューのサイズ調整

スクロールを確認するために「テキスト2」のラベルとテキストフィールドを、コンテンツビューの最下部に移動します。
コンテンツビューをドラッグすると、スクロールビューの表示領域を大きくはみ出しているのが確認できると思います。(図6)
large_content_view2.png
図6 コンテンツビューの高さ

シミュレータで、動作確認しても、まだスクロールの動作をする様子がありません。しかも、Storyboardを4インチで作業していたので、3.5インチのシミュレータでは「テキスト2」のフィールドが隠れてしまって見えません。

これには Auto Layout が関係しています。

Auto Layout


これまで、Auto Layout に関しては、何も意識せずに操作していましたが、Xcode5では、デフォルトでAuto Layout がオンになっています。
右サイドパネルの「File Inspector」を選択して確認してみましょう。Use Auto Layoutにチェックが入っています。(図7)
sb_use_auto_layout.png
図7 Use Auto Layout

Auto Layout の基本は、配置したUIコントロールに対して制約(Constraint)を追加することによって、画面レイアウトを調整します。
この時点で、何も制約を追加していません。何が起こっているかというと、制約が何もないので、ランタイムが自動的に制約を生成して加えているのです。この自動生成は冗長なもので、最適化されたものではありません。
3.5インチのシミュレータで、下のラベルとフィールドが見えなかったのはそのためです。
また、スクロール動作をしない原因は、スクロールビューとコンテンツビューが配置されたままの状態で自動生成され、コンテンツビューの高さは表示領域におさまるように調整されて生成されたようです。

ちなみに、シミュレータの反時計回りまたは時計回りに回転で、Landscape表示してみてください。
コンテンツビューの内容が何も変わらないのがわかると思います。

Auto LayoutのConstraint(制約)を追加


上記の不具合を解決するために、AutoLayoutのConstraint(制約)を追加します。
最初に、スクロールが動作するように制約を加えます。
ScrollViewを選択し、キャンパスの下部ツールバーから、「Pin」をクリックすると、ポップビューが表示されます。(図8)
add_new_constraints.png
図8 制約の追加
表示されたポップビューから上部のアイビームを選択します。図8では上と左の2つが選択された状態ですが、残り2つも選択し、計4つの制約を指定します。数値が「0」を確認して、「Add 4 Constraints」ボタン(図ではまだ2つしか選択いないので「Add 2 Constraints」)をクリックすると。ScrollView に対して4つの制約が追加されます。
図9のように、ドキュメント・アウトラインに4つの制約が追加されたのが確認できます。
add_4constraints_outline.png
図9 4つの制約を追加(ドキュメントアウトライン)
この4つの制約で、スクロールビューが、親であるメインビューの4方向のエッジに対して長さ0でぴったり張り付いた状態を指定しています。回転させてメインビューの大きさが変わってもそれに合わせて変わります。
コンテンツビューを選択して、同様の処理で制約を追加します。今度はスクロールビューを親にした4方向の制約です。(図10)
new_consts_to_content_view.png
図10 コンテンツビューの制約追加

4-inch のシミュレータを実行して、確認します。スクリーンをドラッグしてもスクロールしませんね。
ところが、3.5-inchのシミュレーターにしてみると、スクロールバーが現れて、「テキスト2」のフィールドが見えるようになりました。スクロールしたときのバウンス・エフェクトも確認できます(図11)
sim_scroll.png
図11 3.5-inch シミュレータで動作確認

これはどういうことでしょうか?図12を参照して見てください。下エッジに設定した縦方向スペースの制約をドキュメント・アウトラインで選択して、右パネルのアトリビュート・インスペクターで確認すると、「-82」で固定になっています。
ストーリーボードは4-inchを使用しています。つまり、スクロールビューから見てコンテンツビューのはみ出した分をボトムの制約で固定している状態なので、動けずにいます。
3.5-inch の場合は同じ「-82」でも可動できる部分が残っているのでスクロールできるのです。

fig_scrollable_area.png
図12 コンテンツビューの制約

Auto Layout の命題の一つは、スクリーンのサイズがどんなに変わっても首尾一貫したレイアウトをすることです。これでは、ままならないですね。
ヒントは図12の3.5-inch の部分にあります。
ボトムの制約のConstants の数値を「-82」から「0」にすることで、はみ出した部分を全てスクロール可能にできます。(図13)
change_bottom_edge_constraint.png
図13 ボトムエッジ制約の値を変更

3.5-inch,4-inch両方のシミュレーターで、同じ振る舞いになることろ確認してみてください。

コードを1行も書かずにスクロールする画面を実装できました。
スクロール動作はしているようですが、実は、現時点でこのプロジェクトはまだ問題を含んでいます。
この点に関しては次回「iOS7 - スクロールとちょっとだけ Auto Layout (2)」で説明します。

posted by ayagu at 12:00| Comment(2) | iOS | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
この記事の続きを書いてほしいのですが。。。
Posted by at 2014年11月28日 16:57
この記事の続きを書いてほしいのですが。。。
Posted by key at 2014年11月28日 16:57
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

×

この広告は1年以上新しい記事の投稿がないブログに表示されております。