こんにちは。開発担当のICTFです。
これまでiPhoneといえば画面の大きさは1種類でした。(Retinaか否かという差はありました)
画面の大きさが予め固定ですので、動的にUIを配置する際も座標の決定タイミングを余り気にする必要はありませんでした。
画面がロードされたタイミングにコールバックされるviewDidLoad内にUIの生成と配置を行なっている方も多いのではないでしょうか。
しかしiPhone5の登場により、2種類の画面サイズでUIが正しく配置されるように気をつける必要が出てきました。
画面の種類が増えた事により、UIの座標を設定するタイミングに気をつける必要が出てきました。
例えば、viewDidLoad内で画面の下部に広告ビューを表示するコードを書いてみる事にします。
xibはiPhone4の画面サイズを基準に設計しています。
画面下部に50pxに余白を設けています。テーブルビューは、画面の大きさに関わらず、必ず画面下部に50pxの余白を作るように設定しています。
この余白に広告ビューを表示します。
viewDidLoad内に次のコードを記述します。
※サンプルでは実際の広告を表示するのではなく、広告に見立てたad.pngを表示しています。
- (void)viewDidLoad
{
[super viewDidLoad];
// 広告ビューを画面下部に生成する
UIImageView* adView = [[[UIImageView alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height - 50, 320, 50)] autorelease];
[adView setImage:[UIImage imageNamed:@"ad.png"]];
[self.view addSubview:adView];
}
まずiPhone4で実行してみます。
期待通りに表示されました。もともとxibをiPhon4の大きさで設計していますし、これまで通りの結果です。
次にiPhone5で実行してみます。
広告が最下部に表示されていないどころか、広告の下からテーブルビューがはみ出す程上部に表示されてしまっています。
なぜviewDidLoadで上手く座標の設定が出来ないのかを追ってみましょう。
viewDidLoad内に次のログを仕込んでみて下さい。
NSLog(@"ViewHeight: %f", self.view.frame.size.height);
iPhone5で次のログ出力結果を見てみると、次のようになっています。
iPhone5の縦サイズは548ですので正しい結果が得られていません。460はiPhone4の大きさになりますので、広告はiPhone4の画面サイズから計算して配置していた事になります。
viewDidLoadがコールされるタイミングではまだ画面がデバイスに合わせて拡張されておらず、期待通りのサイズが得られないようです。
iPhone5でも期待通りの位置にUIを配置するには、次のように記述します。
@interface ViewController ()
{
UIImageView* _adView;
}
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// viewDidLoadでは、広告の生成のみ行なう。座標は気にしない。
_adView = [[[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 50)] autorelease];
[_adView setImage:[UIImage imageNamed:@"ad.png"]];
[self.view addSubview:_adView];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// 広告の座標を設定する
CGRect adViewFrame = _adView.frame;
adViewFrame.origin = CGPointMake(0, self.view.frame.size.height - adViewFrame.size.height);
_adView.frame = adViewFrame;
}
これでiPhone5でも正しい位置に広告が表示されるようになりました。
ポイントはviewDidLoadではUIの生成処理のみ行ない、viewWillAppearでは座標の設定のみ行なうという事です。
viewWillAppear内で生成処理を行なうと、画面を表示する度に広告が生成されてしまい、メモリが足りなくなる可能性があるので注意して下さい。
コメントする