iOS開発で少しハマってしまった問題があったので備忘録。
次バージョンの拙作iPhoneアプリ「DoF Table」では、レポートとでも言おうか、アプリが弾き出した計算結果を図とテキストで表示する画面を提供している。この画面はコンテンツ量が多くiPhoneの画面では一度に表示できないので、図やテキストのUI部品を「画面一杯に拡げたUIScrollView」(以後レポート領域)に入れてスクロール表示できるように工夫している。手帳に書いた画面スケッチはこんな感じ:
ところで画面の横幅は機種によって異なる。なのでiOSのAuto Layout機構でもってレポート領域の横幅を画面幅と同じになるよう設定してある。具体的には、レポート領域となるUIScrollViewの「幅は画面と同じ、水平方向は画面全体に対して中央揃え」という設定。これでレポート領域はどの機種でも期待通りの幅になる。まあ、ここまでは基本中の基本なので何も問題無い。
さて今日の問題。レポート領域は期待通りに幅が調整されるのだけれど、その中に配置したUI部品に対して直感に従ってAuto Layoutの設定を行ったところ、まったく期待通りに動作しなかった。具体的には、レポート中の図の幅をレポート領域の幅一杯にまで広げるよう設定したにもかかわらずInterfaceBuilderでの画面デザイン時の大きさのまま変わってくれない。Auto Layoutの制約設定に間違いがあるのかと思ったのだけれど、何度見直しても間違いは無い。さてはて、と思ってネット検索しつつ調べたところiOS 6.0のリリースノートに重要な記述を見つけることができた。一部引用すると:
The constraints on the subviews of the scroll view must result in a size to fill, which is then interpreted as the content size of the scroll view. (This should not be confused with the intrinsicContentSize method used for Auto Layout.) To size the scroll view’s frame with Auto Layout, constraints must either be explicit regarding the width and height of the scroll view, or the edges of the scroll view must be tied to views outside of its subtree.
今回は機種やデバイスの向きで変わってしまう画面幅を絶対値で明示指定はできない。なのでレポート領域内のUI要素のAuto Layout制約はUIScrollViewの「外」にあるUI要素との位置関係で定義してやれば良いということらしい。試しにレポート中の図の一つについて「図の右端は画面※右端-8ptに等しい」などと設定してみたところ、うまくいったようだ。(※この画面はUIViewControllerベースなので、SuperviewであるUIScrollViewではなく一番外側のUIViewの右端を基準にAuto LayoutのConstraintを設定)
さすがにiOSも歴史を重ねてきているだけあって、色々と複雑化しているものなんだなぁ。ともかく、解決できて良かった。よしよし。
さて、もう少し作業を進めるとするかな。