デバッグのためにView階層を把握する

  • 26
    いいね
  • 0
    コメント

※この記事はApple公式の「Debugging View Hierarchies」をベースにして「よくわかるAuto Layout iOSレスポンシブデザインをマスター」を参考にしつつ書いています。ちなみにこの記事執筆時に私が使っているXcodeのバージョンは8.1です。

ビューデバッガーの使いどころ

あるviewがどこにくっついているのかわからない時に使うことが多いと思います。「なんでこのviewは隠れてしまっているんだろう」「removeFromSuperView()してこのviewも消えるはずなのになんで残ってるんだろう」などの疑問を感じた時に役に立ちます。

ビューデバッガーの表示

一番簡単なのはアプリ実行中にXcode下部にあるデバッグバーのDebug View Hierarchyボタンをクリックすることです。
スクリーンショット 2016-12-04 12.45.16.png

もしくはXcodeのメニューバーからDebug > View Debugging > Capture View Hierarchyを選択することでも表示させることができます。

ビューデバッガーを表示すると以下の状態になり、現在のビュー階層を3Dで見ることができるようになります(プロジェクト名が適切でなくてごめんなさい)。
スクリーンショット 2016-12-04 13.32.53.png

左ペインではView Hierarchyが、中央では3Dでビュー階層が、右ペインでは現在選択しているviewの様々なプロパティが見見られるようになっています。中央エリアはドラッグすることで角度を変えてview階層を見ることができます。

View Controls

スクリーンショット 2016-12-04 14.09.31.png
これらのボタンの意味を左から1つずつ説明します。

スクリーンショット 2016-12-04 14.09.31 2.png view間の間隔調節

一番左のバーをいじることでview間の間隔を調整することができ、個々のviewが見やすくなります。

スクリーンショット 2016-12-04 14.29.14.png  スクリーンショット 2016-12-04 14.29.31.png

スクリーンショット 2016-12-04 14.09.31 2.png クリップされたviewの表示

画面外にレイアウトされたオブジェクトはデフォルトだと表示されないので、表示したい場合はこのShow Clipped Contentをクリックします。

スクリーンショット 2016-12-04 15.48.18.png  スクリーンショット 2016-12-04 15.48.28.png

スクリーンショット 2016-12-04 14.09.31 2.png 制約の表示

このShow Constraintsをクリックした後に任意のオブジェクトをクリックするとそのオブジェクトについている制約が表示されます。

スクリーンショット 2016-12-04 16.04.13.png

右ペインのsize inspectorで制約の具体的数値を確認することができます。

スクリーンショット 2016-12-04 14.09.31 2.png 表示モードの変更

スクリーンショット 2016-12-04 16.36.21.png
Contentsモード、Wireframesモード、Wireframes and Contentsモードの3種類があります。

Contents Wireframes Wireframes and Contents
スクリーンショット 2016-12-04 16.37.45.png スクリーンショット 2016-12-04 16.38.01.png スクリーンショット 2016-12-04 16.38.21.png

スクリーンショット 2016-12-04 14.09.31 2.png スクリーンショット 2016-12-04 16.44.01.png 2D⇔3D表示の切り替え

現在2Dの場合は3Dに、3Dの場合は2Dに表示を切り替えるボタンです。

スクリーンショット 2016-12-04 14.09.31 2.png 拡大縮小

このボタンを使うか、トラックパッドでピンチそうさを行うか、オプションキーを押しつつマウスを上下にスクロールすれば拡大縮小操作ができます。

スクリーンショット 2016-12-04 14.09.31.png z軸方面のviewの表示調整

スクリーンショット 2016-12-04 17.07.54.png  スクリーンショット 2016-12-04 17.08.19.png

オプション

「オプション」と称していいのかわかりませんが、右クリックをした時に表示される各項目について説明します。

Print Description of {viewObject}

選択したviewをpoコマンドで出力した時と同様の操作を行うことができます。

実施例
Printing description of $136:
<UIView: 0x7fedba408950; frame = (200 150; 50 150); layer = <CALayer: 0x6080000296a0>>

Focus on {viewObject}

選択したviewとそのサブviewだけが見えている状態になります。
下の例で茶色のviewはその上に黄色のview、さらにその上にオレンジのviewがサブviewとしてある状態なので、茶色のviewにFocus on UIViewを適用すると右のスクショの状態になります。

スクリーンショット 2016-12-04 19.04.00.png  スクリーンショット 2016-12-04 19.04.22.png

Show Constraints

選択したviewオブジェクトについている制約を表示することができます。細かい数値は右ペインのsize inspectorで見ることができます。機能としては先程のShow Constraintsボタンをクリックしたときと同様です。

Hide Views in Front / Hide Views Behind

選択したviewより前の階層、もしくは後ろの階層のviewを隠します。
下の例では茶色のviewを基準にしてHide Views in Front / Hide Views Behindを実行しています。

Hide Views Behind デフォルト Hide Views in Front
スクリーンショット 2016-12-04 19.34.14.png スクリーンショット 2016-12-04 19.28.18.png スクリーンショット 2016-12-04 19.33.57.png

debug navigator

デバッガービューがアクティブの時、debug navigatorには全てのviewオブジェクトが表示されています。親、子、兄弟関係がわかるので、メインウィンドウでの操作よりviewを見つけやすくなります。
左ペインで任意のviewを選択すると、メインウィンドウで該当するviewが薄く色づきます(赤いviewがちょっと青くなってます)。
スクリーンショット 2016-12-04 20.21.45.png

filter bar

左ペインの一番下にfilter barがありますが、そこには2つのフィルターボタンが存在しています。
スクリーンショット 2016-12-04 20.32.27.png

Show primary views

このフィルターはアプリのコントロール下にない2つめのビューオブジェクトを隠すものです。例えばUIButtonの場合後ろのviewとUILabelで構成されているので、フィルターがONになっている時は1つのviewしか見えません。フィルターがOFFになっている時は中央の3Dエリアでサブビューも見えている状態になります。
…と思っていたのですが想定通りになりません。Xcode7で試しても同じでした。何かご存知の方は編集リクエストやコメントをいただけると幸いです。

Show only displayed views

このフィルターがかかっていると見えないviewは左ペインで表示されません。つまりisHiddenがtrueになっていたら見えません。
下の例では右がフィルターON、左がフィルターOFFの状態です。buttonのisHiddenをtrueにしているので、フィルターがONの時は見えていません。
スクリーンショット 2016-12-05 0.12.57.pngスクリーンショット 2016-12-05 0.12.45.png

text filter

左ペインに表示されているviewをテキスト情報で絞り込みたい時に使います。単純にクラス名はもちろんのこと、ボタンタイトル、メモリアドレスでの絞り込みにも対応しています。クラス名で入力した場合、サブクラスも表示されるようになっています。
■ボタンタイトル
スクリーンショット 2016-12-11 20.13.46.png
■メモリアドレス
スクリーンショット 2016-12-11 20.13.25.png
■サブクラス表示
スクリーンショット 2016-12-11 20.29.11.png

debug navigatorが役に経った例

実際の業務で役に立った例を紹介します。
画面全体を覆っているviewをremoveFromSuperView()してそのviewとその上に乗っかっているviewを取り除こうと思ったのですが剥がれて欲しいviewがくっついたままでした。茶色いviewのセットも剥がれてほしいのになぜか剥がれていないという状況でした。

初期状態 removeFromSuperView()後
スクリーンショット 2016-12-09 11.14.49.png スクリーンショット 2016-12-09 11.16.11.png

3Dのエディタをぐるぐる回してみてもgrayのviewに乗っかっているように見えて「はて?」と思っていたのですが、debug navigatorを見たらすぐ原因がわかりました。
スクリーンショット 2016-12-09 11.32.48.png

brown viewはgray viewにくっついているわけではなくself.viewにくっついているということがひと目でわかりました。

オブジェクト、サイズインスペクター

左ペインもしくは中央のエディタでオブジェクトを選択すると、オブジェクトインスペクタ、サイズインスペクタに属性値が読み込まれます。オブジェクトインスペクタはそのオブジェクトが持っている特性値を表示し、サイズインスペクタはそのオブジェクトのサイズ情報やAutoLayoutの制約情報を表示します。

アシスタントエディタ

アシスタントエディタは下図右上の丸が2つ重なったボタンをクリックすることでON/OFFの設定ができます。アシスタントエディタを自動モードに設定すると、選択したビューオブジェクトのソースが表示されます。下図では緑色のviewを選択しているのでUIViewのヘッダが表示されています。
スクリーンショット 2016-12-06 23.51.12.png

その他Tips

debug navigatorの表示ショートカット

中央のメインウィンドウでviewや制約を選択した状態でCommand + Shift + Dをすると選択したviewがハイライトされた状態で左ペインのdebug navigatorに表示されます。

曖昧なレイアウトの警告

ビューデバッガー表示中に曖昧なレイアウトがあるとこのように紫のビックリマークが表示されます。この紫ビックリマークのRuntime issuesはXcode8から出てきました。スレッド周り、UI周り、メモリ周りの問題を指摘してくれます。
スクリーンショット 2016-12-09 11.40.39.png
クリックするとこんな表示が出てきます。
スクリーンショット 2016-12-09 11.44.32.png
どうやら縦方向の位置が曖昧らしいです。
debug navigatorで警告表示をクリックすると該当のview(今回はオレンジ色のview)が青くハイライトされます。
スクリーンショット 2016-12-09 11.46.59.png
この紫ビックリマークはdebug navigatorでも表示されますし、size inspectorでどのように曖昧なのか教えてくれます。
スクリーンショット 2016-12-11 20.48.45.png