写真鑑賞アプリ【 Viewing Fun ! 】

2013年7月20日土曜日 | Published in | 0 コメント

このエントリーをはてなブックマークに追加

新しいアプリをリリースしました。Viewing Fun !という写真ビューアです。自分自身が欲しいと思っていた写真ビューアを形にしたアプリです。

ランディングページ Viewing Fun !


今日の投稿はそのプロモーション記事です。


特徴

カメラロールの写真を見るためのアプリ。写真は1日単位で1ページにまとめられていて、3つのビューで写真を眺めることができる。
※スクリーンショットは古く最新版と若干異なります。


「アルバム」ビュー


1日の写真を大小様々な大きさの枠に自動配置して表示するビュー。写真をタップすると全体表示ができる(すべてのビューで共通)。


左右にフリックすると前日・翌日と移動ができる(これは3つのビューで共通)。


「マップ」ビュー


1日の写真とその撮影場所の地図を同時に表示するビュー。


番号で写真と地図が対応づけられている。写真はフリックで上下にスクロールできてそれに合わせて地図もスクロールする。写真と地図を眺めながら時間軸に沿って撮影場所を追っていくことができるようになっている。


「タイムライン」ビュー


1日の写真を時系列に並べたビュー。


デフォルトで1時間単位に折りたたまれていてタップすると開閉する。時系列に写真を見ながら撮影時の状況を追体験できる。


カレンダービュー


月単位で写真が眺められるビュー。


左右にフリックすると前月、翌月と移動できる。日付の色は写真の枚数によって青(薄い)〜赤(濃い)と変化する。


スライドショー


ズームとスクロールによる動きのあるスライドショーをランダムに表示する。約4秒間隔で写真が切り替わっていく。


カジュアルにスライドショーが楽しめるようトップレベルに開始ボタンを設置していて、設定無しですぐに始まるようにできている。


コンセプト


私は週末など出掛けた時にiPhoneを使って数十枚の写真を撮影しますが、多い時には100枚以上にもなることもあります。これを後からiPhoneで手軽に見返したいというのがこのアプリ開発のきっかけでした。作る前にはいろいろなアルバムアプリを購入して試してみましたが自分が欲しいものが見つからなかったというのも動機の一つでした。どれもしっくりこないのです。その大きな理由の一つとして、ほとんどのアプリは「整理する」ことがメインで、「見る」ことはどちらかというとオマケ的だと思えたからです。もちろん「見る」機能自体はどのアプリもしっかり作りこまれているのですが、ほとんどのアプリで写真閲覧のユーザインターフェイスが標準のアプリとほとんど同じでした。私の場合、写真整理はしないので、写真を見るなら標準アプリでも十分でわざわざアルバムアプリを使う理由がありません。それとこのユーザインターフェイスが出てから数年経つのに工夫が感じられない点も不満を感じていました。そんななか次の自作アプリのネタを探していたこともあり、無いなら作ってしまえとばかりに開発を始めることにしました。開発するにあたっては「見る」ことをメインとして「整理」は二の次、いや無くても良いぐらいの考えでイメージを考えてプロトタイプを作り始めました。今までのアルバム・ビューアに感じていた「見る」点の不満を解消して新しいアルバムアプリ(ビューア)を形にすることを目標にしました。

アプリ開発でこだわったのは次の点です。
  • 整理しないアルバム
  • 見ることが一番
  • 非サムネイル
  • 追体験
  • 1日でまとめる


整理しないアルバム


矛盾するフレーズですが「手動で整理しない」というくらいの意味です。人間が手で整理しなくてもコンピュータが自動的に整理してくれて手軽に写真が楽しめるのが今後の写真アルバムのあるべき姿だと個人的には思っています。iOS7の新しい写真アプリを見ると自動整理の兆候がちょっぴり見られますよね。現在人間が手動で整理せざるを得ないのは、人の好みに合わせて自動的に整理できるような高度な写真アルバム(アプリ)が無いからで、いずれ整理のメインは自動になると予想しています。理由は単純で、スマホの出現によって手軽に写真が取れるようになった一方、撮り貯めた写真が膨大になってきていて人間の手では整理しきれなくなりつつあるからです。

と、大げさに書いたもののこのアプリ自体は自動整理といっても1日単位にまとめるぐらいしかやっていません(自動と呼べるかも疑問ですが)。そして整理機能を持たない一番の理由は、私自身がものぐさで写真の整理ができない、だから使わないというのが理由です。また世の中の多くの人が恐らくそうだろうとも仮説を立ててみました(ものぐさなのは私だけじゃないですよね...?)。なので「整理せずに写真を手軽に楽しめる」ということがアプリの中心コンセプトとなりました。その為にはどういうビューや機能を用意すべきか、と。


見ることが一番


アルバムアプリの機能は大きく「見る」(鑑賞する)ことと「整理する」ことの2つだと思います。ただ多くのアルバムアプリは後者に力点が置かれていて、前者の「見る」機能が正直なところなおざりにされていると感じました。もちろん「見る」機能はちゃんとあるのですがiPhone標準の写真アプリとほとんど変わらないサムネイルと全体表示のスライドショーの構成、アプリによってはカレンダーと地図表示があるぐらいでした。アルバムアプリを見るにつけて常にこの点が不満でした。せっかく「整理する」機能はどれも工夫されているのに、一番利用することが多いだろう「見る」ことがあまり深く考えられていません。アルバムアプリは「整理」が主目的と言われればそれまでなのですが。。
だからこのアプリでは前述の「整理しない」ことと合わせて「見る」ことを最優先に考えました。複数のビューに加え、動きのあるスライドショーを入れたは、まさに「見る」ためです。またスライドショーに関しては、他のアプリと違いこのアプリで開始ボタンがトップ画面で目立つところにあります。このボタンをワンタップするだけで面倒な設定もなしでいきなりショーが開始されます。これはスライドショー自体をスキマ時間に楽しんでもらえるようなカジュアルなものにしたかったからです。またズームや移動を盛り込み、順番もランダムにして飽きさせないような工夫もしてあります。

なおスタンプを貼ったり、デコレーションしたり、様々なレイアウトフレームに配置したり、といったアプリはたくさん出ています。この点、「見る」ことに関して実際はいろいろと工夫されていると思います。ただし、それらの機能を持つ多くのアプリはコミュニケーションのツールとしての利用(友達に渡す、仲間と共有するなど)が前提で、写真自体を鑑賞する目的のアプリはあまりありません(いやあることにはあったのですが自分の用途にはイマイチでした。。


非サムネイル


サムネイルを否定しているわけではなくiOS標準の写真アプリを起源に持つステレオタイプ的なUIを指してしています。世に出回っているアルバムアプリは、最初にサムネイル表示されていてタップすると全画面モードを表示するものがほとんどです。これに加えて地図やカレンダーが付いているものもありますがそれらの画面でもサムネイルが基本です。このサムネイルはたくさんの写真を並べるには効率的ですが、普通に眺めるのには小さすぎます(老眼になりつつあるおじさんの眼では正直つらい..)。とても写真を楽しむ大きさでは無いと思ってました。かといって全画面モードではたくさんの写真を効率的に見ることができません。現在の多くのアルバムアプリはこの中間が抜けているのです。多くのアルバムがこのスタイルを取っているのはiPhoneの画面が小さいということもありますが、一番の理由は標準の写真アプリがこのスタイルだからでしょう。そこになんの工夫が無い点も開発者の立場から言えば不満でした。

そこで一番最初にプロトタイプを作った時にはまずサムネイルではなく、画面の1/2〜1/3程度の大きさで写真を並べるところから始めました。その結果、いくつもの写真を眺めるにはサムネイルよりも視認性が良く手軽に写真を楽しむのにはある程度の大きさがある方が良いことが実感できました。最初のプロトタイプを作ることで方向性が見えてきたので、それから自分が納得のいくビューができるまでは、作っては捨て・作っては捨ての繰り返しでした。ビューを試作したらすぐに手持ちのiPhoneへ入れて、移動中の時間などにそのプロトタイプ・ビューを自分で何度も何度もいじって使い倒しました。最終的には今の3つのビューになったわけですが、そこへ至るまでは結局プロトタイプで1ヶ月以上、最後のビューへ落ち着くまでは3ヶ月はかかりました。最後の最後の段階で切り捨てたビューもあります。実はサムネイル画面も用意しましたがこれも途中で捨てました。作ってみたもののやはりしっくりこなかったからです。なおカレンダー画面にはサムネイルが残っていますが、これはむしろサムネイルがぴったりの用途だからです。カレンダーは1ヶ月という単位で時間を俯瞰するので、そこで表示される写真も俯瞰的に見えた方が統一感が得られるからだと思いました(ちっちゃいけど)。


追体験


写真をとったあの時を今の自分が追体験すること、別の言い方をすると「撮影時のストーリーを思い出せる」こと、それが写真ビューアに求められることだと考えました。一番原始的なところでは写真を撮った日時とその時の場所が見られるということです。もちろん日時と場所の情報はほとんどのアルバムアプリでも見られます。しかし日時と場所を写真の単なる付加情報としてしか捉えていなくて、どちらかといえばオマケのように感じられました。そうではなく、写真を見る人が日時と場所を知りたいのは、その写真をとった時の状況を思い出すきっかけになるからです。私は、日時と場所の情報はその時を思い出す為の重要な情報だと考えています。それは「撮影時のストーリー」を思い出すきっかけであり、その写真をとった時のことを今の自分自身が追体験することへ導くからです。だから場所の情報は緯度・軽度ではなく地名で表示するのが自然でした。地図表示ももちろん役立ちます。幸いiOSのAPIには緯度・経度を元に地名を取得するものがあったので今回はこれを利用しています。今回はできませんでしたができればその時の天気やその土地の情報なども盛り込みたいとも思ってます。

このアプリでは、写真ごとの日時と場所の表示を基本とした上で「タイムライン」と「マップ」と呼ぶそれぞれ時間と場所を軸とする2つを用意しました。「タイムライン」は1日の写真を時系列に1時間単位に並べたものです。これは実際に見てもらうとわかるのですが写真と地名が時間に沿って表示されるのでその1日の行動を写真付きで後から時系列に眺めることができます。時系列にならんだ写真と地名を俯瞰できるので1日の行動の流れを思い出すのに役立つと思います。もう一つの「マップ」は上部に地図、下部に写真という構成になっています。特徴的なのは地図上のピンに番号がついていてそれが時間順になっていることです。つまり行動の足あとを後から追えるようになっています。写真にもこの番号がついていて、この写真がどの場所で取られたのかを地図上で容易に確認できます。この写真を上下にフリックするとそれに合わせて地図上の表示も変化していくので、写真をめくることで行動の軌跡をやはり自分で追体験することができます。


1日でまとめる


この考えは開発初期にはすでに固まってました。人が過去を思い出す時の時間の単位は1日が自然だと思ったからです(あの日にどこどこへ行ったんだっけ、みたいな)。開発初期にはよくあるように1枚の画面に全ての写真をならべ、セクション(見出し)に日付を付けるようなUIを試していました。しかしこのUIは大量の写真を扱うにはサムネイルにせざるを得ない為あきらめました。また1画面に複数の日の写真が同時に目に入ってくる為に「追体験」という意味では写真が楽しめない(集中できない?)と感じました。思い出の単位が1日なら、見せ方もそれに合わせた方が自然ではないかと。それらの理由から1画面で表示するのは1日分の写真だけ、という今の基本UIに決めました。ただこの時どうやって他の日へ移動するかが課題になります。これには左右へのフリックを割り当てました。一方、上下のフリックは1日の中の時間軸の移動に統一してあります。この2つのルールは3つのビューで共通です。なおスライドショーのみはこのルールから外して左右フリックとしました。開発中に上下フリックを試してみたのですがかなり違和感があったからです。こうして1日単位のUIが定まると今度は任意の日へ移動する手段が必要なります。その為にカレンダーのビューを作りました。この点、多くのアルバムアプリが取っているカレンダービューを基本としているのとは真逆のアプローチとなりました。


-----

とまあ色々書きましたが、気軽に楽しめるアプリです。
無料なので良かったらどうぞ試してみて下さい。

Viewing Fun !




10分でおぼえるBlocksの書き方

2013年7月18日木曜日 | Published in | 0 コメント

このエントリーをはてなブックマークに追加

Blocksが使えるようになってはや数年。未だに書式が覚えられないわたし(あなた)の為に書き方をまとめてみた。

基本


基本型


 戻り値 (^名前) (引数)
(私が勝手に決めた)基本型はこれ。これを覚えないことには始まらない。とにかくこれだけは覚える。
戻り値と引数は一般的なCの関数の書き方と同じなので、名前の書き方だけ (^名前) になったと覚えるのがいい。
(例)BOOL (^completion)(BOOL canceled) = ...;
この基本型を元に各場面でどう使うかを見ていく。

変数宣言・typedef宣言


変数宣言なら
 戻り値 (^名前) (引数) = …;
typedef宣言なら
 typedef 戻り値 (^名前) (引数);
両方とも基本型がそのまま使える。

(例)typedef BOOL (^LKCompletion)(BOOL canceled);

プロパティ宣言


プロパティ宣言で使う時にも基本型がそのまま使える。
 @property (copy) 戻り値 (^名前) (引数)
Blocksをプロパティ宣言する場合は copy にしておくのがポイント。
(例)@property (copy) BOOL (^completion)(BOOL canceled);

メソッド引数


メソッド引数にした時に書き方が若干変わる。形が変わるのが Blocks構文を覚えにくくさせている理由の一つ。
(例)- (void)loadImageCompletion:(BOOL(^)(BOOL canceled))completion;
ただ落ち着いて見るとObjective-C標準のメソッド引数の書式に従って基本型を変形しているだけなので実は難しくない。

もともとメソッド引数は「(型)名前」というスタイルなので基本型をそれに合わせて変形ればいい。
戻り値 (^名前) (引数)  ※基本型
 ↓
 ↓ 名前を後ろへ切り出す ←メソッド引数名は最後にくるから
 ↓
戻り値 (^) (引数)名前
 ↓
 ↓ 引数の型となる範囲を( )で囲う ←メソッド標準の書き方
 ↓
(戻り値 (^) (引数)) 名前
基本型をメソッド引数の書き方に合わせたものだと覚えておくといい。


Blocks定義


 ^戻り値 (引数) {...}
やはりBlocks構文を覚えくくさせている原因の一つ。基本型と書き方が異なる。
(例)BOOL (^display)(BOOL animated) = ^BOOL(BOOL animated) {return YES;};
こちらはメソッド引数の時と異なり変形ルールが想定できない。仕方がないので基本型同様に暗記する。なおメソッド引数にBlocks定義を記述する場合、Xcodeならコーディング時にBlocksの書式を補完してくれる。この為記憶を頼りに記述するケースは実際には多くないかもしれない。

(例)[hoge loadImageCompletion:^BOOL(BOOL canceled) {
    :
   }];


まとめ


こうして見ていくとBlocksの書き方が覚えにくいのには理由があって、書き方のパターンが何種類もあるのが原因だとわかる。逆にそれらが整理できて把握できれば自分で書けるようになる。

最低限覚えるべきは次の2つ。

基本型

 戻り値 (^名前) (引数)

Blocks定義

 ^戻り値(引数) {...}
それ以外は基本型がそのまま使えるのと、メソッド引数の場合は基本型の応用なので変形ルールを知っておけば書式を無理に覚える必要は無い。またBlocks定義を書く時は、多くの場合 Xcodeが補完してくれるので覚えておく必要性は基本型に比べると実は少ない(人によるが)。なので、乱暴に言えば基本型だけ覚えればどうにかなる。

なお「基本型」など、この記事の分類は私が勝手に決めたものなのでご注意を(公式の呼び名ではない)。


応用


voidな引数と戻り値は省略できるケースがある。

引数省略


引数が voidの場合は省略できる。

BOOL (^execute)(void) = …;
 ↓
BOOL (^execute)( ) = …;
- (void)displayScreen:(void(^)(void))didAppear;
 ↓
- (void)displayScreen:(void (^)( ))didAppear;

戻り値省略


Blocks定義の時は戻り値が voidであれば省略できる。
(例)^void (void) { … }
    ↓
   ^(void) { … }
Blocks定義の場合、引数が voidならさらに引数のカッコ ()自体も省略できる。
(例)^{ … }
よく見かける ^{...} は実は ^void(void){...} が省略されたもの。

Blocks定義以外で戻り値voidは省略できないので注意。
○ @property (copy) void (^didAppear)(BOOL animated);
☓ @property (copy) (^didAppear)(BOOL animated);


参考・お役立ち情報


Block Cheat Sheet

Block Declaration Syntax List
Recursive Blocks(再帰ブロック)の書き方の紹介あり。

坂本氏担当の第5章にBlocksの説明あり。GCDと合わせてわかりやすい。


こちらも坂本氏の本。詳細な解説だがそれでいてわかりやすい。ARCの詳説もあるのでかなりおすすめ。私は紙で入手したが電子書籍版もあると思う。



- - - -
ツッコミあればお願いします。間違い等は訂正します。

人気の投稿(過去 30日間)