前回の続き。今回は異なる端末サイズや回転を意識したframeを設定について解説。

固定値ぶちこみは禁じ手

iPhone 5は従来の端末と高さが異なりますし、iPhoneとiPadも端末のサイズが異なります。

_tableView.frame = CGRectMake(0, 0, 320, 460);

こういう直接代入はもはや通用しないと思ったほうがよいでしょう。320、460という値をdefineするのも良くないです。回転してレイアウトを変えるときの対応にも弱いです。

Subviewの配置範囲はSuperviewのboundsに従う

プログラムからframe設定するときはSuperviewのboundsを参照し、その範囲に収まるように配置するべきです。boundsのorigin.x、origin.yは常に0なので、実際はbounds.sizeを参照すると言ったほうがよいかもしれません。

Subviewのframeの計算方法

よくありがちなSubview配置について説明します。

UIViewControllerの場合は、まずself.view.boundsをローカル変数に代入

CGRect bounds = self.view.bounds;

view全体に貼り付ける

_tableView.frame = bounds;

上下左右に8pxの余白を持たせて全体に配置する

CGRect tableViewFrame;
tableViewFrame.origin.x = 8;
tableViewFrame.origin.y = 8;
tableViewFrame.size.width = bounds.size.width - 8*2;
tableViewFrame.size.height = bounds.size.height - 8*2;
_tableView.frame = tableViewFrame;

100 x 37pxのUIButtonを中央に配置

CGRect buttonFrame;
buttonFrame.size.width = 100;
buttonFrame.size.height = 37;
buttonFrame.origin.x = (bounds.size.width - buttonFrame.size.width) / 2;
buttonFrame.origin.y = (bounds.size.height - buttonFrame.size.height) /2;
_button.frame = buttonFrame;

100 x 37pxのUIButtonを右側に配置。その左側にUITextFieldを配置。左右のマージン8px、UIButtonとUITextFieldのマージン8px、UITextFieldの幅は可能な限り広く。

CGRect buttonFrame;
buttonFrame.size.width = 100;
buttonFrame.size.height = 37;
buttonFrame.origin.x = bounds.size.width - 8 - buttonFrame.size.width;
buttonFrame.origin.y = 8;
_button.frame = buttonFrame;

CGRect textFieldFrame;
textFieldFrame.origin.x = 8;
textFieldFrame.origin.y = 8;
textFieldFrame.size.width = buttonFrame.origin.x - 8*2/*画面左マージンとボタンとのマージン*/;
textFieldFrame.size.height = 37;
_textField.frame = textFieldFrame;

こんな風に書くと大変そうと思うかもしれません。しかしパターンは決まっているので、慣れるとすぐ書けるようになります。たぶん・・・

ちなみに、

_textField.frame = CGRectMake(8, 8, buttonFrame.origin.x - 8*2, 37);

このようにせずにCGRect変数を定義しているのは、この方がバグったときにデバッガで追いやすいからです。

次回はAutoresizingMaskと合わせて説明します。

その3へ続く