Sunflat のブログ

ソフトウェア開発についての話題が多いかも

iPhone SDK Tips #1

iPhone SDKNDAが変更になって、リリース済みのiPhone OSの内容については公開しても良くなったみたいなので、iPhone SDKのTipsをいくつか書いてみる。

UIAccelerometerの謎

UIAccelerometerクラスを使うと、加速度計の値が定期的に取得できるようになるけど、どうもタイマが不安定みたいで、以下のような現象がおこる

  1. まれに、加速度計の値が取得できなくなることがある( - [UIAccelerometerDelegate accelerometer:didAccelerate:] メソッドが呼び出されない)。
  2. 加速度計の値の取得が遅延する。100Hzで取得するように設定しても、実際には86Hz程度でしか取得できない

1.に関しては、accelerometer:didAccelerate:が呼び出された時にカウンタをインクリメントするようにして、定期的(0.5秒程度)にカウンタの値をチェックし、カウンタが増えていなかったら、以下のようにしてUIAccelerometerをリセットすると、正常に戻るみたい。

[[UIAccelerometer sharedAccelerometer] setDelegate:nil];
[[UIAccelerometer sharedAccelerometer] setUpdateInterval:(frequency)];
[[UIAccelerometer sharedAccelerometer] setDelegate:(delegate)];

2.に関しては、上記のカウンタの値を見て、必要に応じてパラメータ(ローパスフィルタの係数など)を調整する、みたいな感じが良いのかな

landscape(横向き画面)モードで表示

以下のようなメソッドを、UIViewクラスに(適当なカテゴリを作って)追加しておいて、

- (void)applyInterfaceOrientation:(UIInterfaceOrientation)orientation {
    UIView *view=self;
    if (orientation==UIInterfaceOrientationLandscapeRight) {
        // ステータスバー非表示の場合の計算
        CGSize size = view.bounds.size;
        view.center = CGPointMake(size.height / 2, size.width / 2);
        view.transform = CGAffineTransformRotate(CGAffineTransformIdentity, (M_PI / 2.0));

        // ステータスバーを表示する場合の計算式は、公式のiPhone OS Programming Guideに書いてある。
    }
}

こんな感じでlandscape表示。

[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];
[view applyInterfaceOrientation:UIInterfaceOrientationLandscapeRight];

(追記:以下、最新のファームウェアでは不要)

UIViewControllerの場合は、- [UIViewController shouldAutorotateToInterfaceOrientation:] を実装すれば、デバイスの向きに応じて自動回転してくれるはずなんだけど、起動直後は常にportrait(縦向き画面)モードになってしまう…

とりあえず、以下のように手動でサイズ変更&回転させるとうまくいった。(showInView:メソッドでビュー表示)

- (void)showInView:(UIView *)superView {
    [superView addSubview:self.view]; // ここでPortraitモードに戻ってしまう
    [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight];
    self.view.bounds=CGRectMake(0,0,480,320);
    [self.view applyInterfaceOrientation:UIInterfaceOrientationLandscapeRight];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
	return interfaceOrientation==UIInterfaceOrientationLandscapeRight;
}

OpenGL ES 利用時に、画面がちらつく場合がある

2つの画面がswapされて表示されるようだけど、片側の画面がちゃんと描画されず、画面がちらついて表示される場合がある。

ビューを再追加すると直るっぽい(?)が、プログラム側で上記現象を検出する方法が不明なので対処できない。めったに発生しない(数時間に一回とか)ので、デバッグが難しい。

原因不明。困ってます

SafariからAppStoreが開けない

どうも、ファームウェア2.1だと、Webサイト上にAppStoreのアプリへのリンク( http: //phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=XXXXXXXX )を書いても、iPhone上のSafariから開けなくなってしまったようだ。
メールや、他のアプリから上記URLを開く場合は、ちゃんと動作する。あくまでSafari上でのみの問題。
ファームウェア2.0.Xの時はちゃんと開けたのだが、単なるバグだろうか? 早く直して欲しい…


=> ファームウェア2.2で直っていました

ゲームアプリにつけておいたほうが良い機能

以下のような機能は、よく要望があるので、iPhone向けのゲームアプリを作る場合はつけておいた方が良いかも

  • ポーズ(一時停止)機能
  • 加速度計のキャリブレーション機能
  • リプレイボタン(ゲームオーバー時に、すぐに再プレイ)
  • Music/iPodアプリで演奏中の音楽を、停止せずに遊ぶ機能
    • OpenALとかを使うと、音楽が停止してしまうので、オプションで音を鳴らさない(OpenAL APIを一切呼び出さない)モードを用意する
  • ハイスコアの保存、スコアランキング