SimpleBoxes

FloatyMemo / FloatyMemo+ ver 1.09 リリース

FloatyMemo ならびに FloatyMemo+ ver 1.09 がリリースされました。

今回は FloatyMemo+ で「メモ一覧」をサポートしたのがもっとも大きな変更になります。

iTunes Store で頂いた takuxya さんの要望

できれば、
■□□□□□□□・・・
↑の現状の仕様通り、右にページが増えるモードと別に、

□□□
□■□
□□□
↑のようにタイル状にページが増えるモードが欲しいです。
一番右のページまでスクロールさせるのが結構時間かかるので。

[→FloatyMemo+ カスタマレビュー]

をアレンジして実装した形になります。アイデアをご提供いただき、ありがとうございました。

新たに追加された「メモ一覧」ボタンをタップするか、ページ自体をピンチすることで「メモ一覧」モードに移行します。

FloatyMemo+ 自体は横一列にページが配置されていますが、ページ一覧ではスペースをより効果的に利用するため、各ページがタイル状に配置されます。

[イメージ]メモの一覧表示

以下、技術的なお話。

「メモ一覧」では、各ページのスナップショットをイメージとして取得して、それをタイル状に並べることで実装しています。

この「スナップショット」は、UIKit の UIGraphicsGetImageFromCurrentImageContext() 関数を利用することによって実現しています。

ただ、そのままの実装だと、最大までページを追加した状態 (16 ページ) だと、簡単にメモリ不足に陥ってしまい、OS から強制終了されてしまいます。

とくに初代 iPad だとあっさり落ちることが多く、メモリ不足で強制終了された場合、デバグもできない状態になります。

最初はメモリの警告を受け取ったら、それ以降はサムネイルを作成しないようにしたんですが、一部しかページサムネイルが表示されないのはあまりにあんまりです。

UIKit のドキュメントをつらつら見ていたら、UIGraphicsBeginImageContextWithOptions 関数に気づきました。

イメージコンテキストを初期化する関数 UIGraphicsBeginImageContext に追加のオプションが指定できる関数で、iOS4 から利用できます。

この関数の三番目の引数 CGFloat scale で iPhone4 などの Retina ディスプレイでは高解像度のイメージが取得できます。

UIGraphicsBeginImageContextWithOptions(view.bounds.size,
                                       view.opaque,
                                       [[UIScreen mainScreen] scale]);

のように [[UIScreen mainScreen] scale] を渡すとデバイスの解像度に応じたイメージが取得できます。

この scale に実際の解像度より小さい値を渡すと、実際よりも低い解像度のイメージを取得することもできます。そうすることで使用メモリも大幅に減らすことができます。

今回のようにサムネイルとして利用する場合は、実際の解像度は必要ありません。むしろ利用するメモリを制限するために、あえて低解像度のイメージを取得するようにします。

UIGraphicsBeginImageContextWithOptions(view.bounds.size,
                                       view.opaque,
                                       [[UIScreen mainScreen] scale] * 0.5);

これで初代 iPad で最大ページを利用していてもかなり安定して動作するようになりました。

iOS4 より前の OS でも動作するようにするためには UIGraphicsBeginImageContextWithOptions が利用できるかチェックする必要があります。

if (UIGraphicsBeginImageContextWithOptions != NULL)
{
  UIGraphicsBeginImageContextWithOptions(view.bounds.size,
                                         view.opaque,
                                         [[UIScreen mainScreen] scale] * 0.5); 
}
else
{
  UIGraphicsBeginImageContext(view.bounds.size);
}
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage* image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

iOS4 より前では、解像度の指定はできなくなってしまいますが、マルチタスクでもないため、とりあえず、これでよいかなと思っています。

スポンサーリンク

<< OS X Lion で FastCGI を利用する :: ラグビーワールドカップ 2011 日本 vs フランス >>