インコ式静岡新聞の作り方的な話

[Appcelerator Titanium Advent Calendar 2015 2日目](http://qiita.com/k0sukey/items/1c2060fbcb041248ba78) で書いた、[インコ式静岡新聞](http://inkoshiki.jp)の技術的なお話になります。こんにちは。

さて、インコ式静岡新聞はとてもシンプルなアプリではありますが、なかなか細かなテクニックがいくつか詰まっていますので、それのご紹介をしていければと思います。まあ多分 Objective-C や Java なら簡単にできるよ！といったこともいくつかあるとは思いますが、ぼくは JavaScript が大好きなので、あえて茨の道になってしまうかもしれませんが Titanium なのです。

## 透明なナビゲーションバーを作る

以前、[こちらの投稿](http://qiita.com/k0sukey/items/b9347d7e3868df7c0c1b) で書きましたが、それのフォローアップ版だと思っていただければ。

```Ti.UI.Window``` の ```barColor``` に ```transparent``` を指定したり、```barImage``` に透過画像を指定してもナビゲーションバーに影のボーダーが残ってしまうのでは、```hideShadow``` を ```true``` にすることで回避できると以前の投稿で書きました。ただ、これだけですと、透明になったナビゲーションバーの存在は残ってしまいます。ここに ```Ti.UI.TableView``` 等のリスト系 UI パーツを配置してスクロールすると、ナビゲーションバーが存在する場所でリストが途切れてしまいます。そんなときは、あわせて ```extendEdges``` プロパティを指定してあげましょう。```[ Ti.UI.EXTEND_EDGE_TOP ]``` を指定することで、ナビゲーションバーを残したままリストが途切れることなく表示することができます。
```extendEdges``` は、```translucent``` プロパティを ```true``` にした際、ナビゲーションバーに擦りガラス効果をつけた際、リストをナビゲーションバーの下までスクロールした際に表示させて、滲んだような表示をしてくれます。今回は透明なナビゲーションバーなので、そのまま表示されているように見えますね。

## Ti.UI.ScrollableView を縦にスクロールさせる

この UI パーツは通常、横にしかスクロールさせることができません。iPhone のホーム画面なんかがこれになりますね。インコ式静岡新聞では、ニュースを表示している画面で使っています。

簡単なことですが、```Ti.UI.2DMatrix``` の ```rotate``` メソッドで 90 度回転します。これだけですと、中に追加された UI パーツまで回転してしまうので、追加された親の UI パーツを今度は -90 度回転します。これで見た目もバッチリですね。```Ti.UI.ScrollableView``` 自体の ```width``` と ```height``` は、それぞれ ```width``` には ```Ti.Platform.displayCaps.platformHeight``` を、```height``` には ```Ti.Platform.displayCaps.platformWidth``` 指定してあげてください。Android の場合は ```Ti.Platform.displayCaps.logicalDensityFactor``` の考慮も忘れずに。

## インコの着せ替え

お察しの通り、```Ti.UI.ScrollableView``` が三段構えになっております。画像自体は画面サイズいっぱいになっているので、```top```、```width``` / ```height``` それぞれを良い感じの座標やサイズで区切ってあります。これを、各画面サイズ分設定ファイルに持っていて、起動時に画面サイズから算出しています。

地味な作業でしたが、これが一番きついかもしれませんね。Android とか Android とか Android とか...。

## 時計

アプリホーム画面の時計、ありますよね。これ、長針と短針がじみーーーに動いているの、知っていました？針を動かすアルゴリズムはネットにありますのでググってみてください。

この時計は皆さん大好きな ```setInterval``` で動かしています。はい、危険な香りがしてきましたね。大丈夫です。手厚くフォローしてあげれば怖くないです。やりっぱなしにするのが悪いんです。
どんなフォローかといいますと、画面が遷移した際にタイマーを停止しています。```clearInterval``` ですね。実は画面が遷移したとしても ```setInterval``` が勝手に停止するかというと、そうではありません。自分で止めてあげないといけません。なので、```setInterval``` するときは、必ず戻り値のタイマー ID を保持してください。回しっぱなしにするのがいけません。
もちろん、アプリがバックグラウンドに移行した際も停止してあげてください。レジュームイベントで、また動かしてあげれば良いだけです。```setInterval``` する際のお約束ですよ。

## その他、細かなお約束とか

### コントローラに、Ti.UI.create〜 しない

ぼくは絶対にしません。必ず別のビューコントローラを作ります。なぜかというと、歯止めが効かなくなるからですね。確かに楽なのですが、本当にやりたい放題になってしまいますので...。そして、クラシックスタイルのコードはあれだけ見づらい見づらいと言われてきて、せっかく Alloy が登場したのにまた昔へ逆戻りとか、ちょっと考えられません。自ら見づらいコードを書くなんて墓穴は掘らないですよ。
ただ、```Ti.UI.2DMatrix / 3DMatrix``` は別ですよ。これはコントローラに直書きしないと無理ですし、これを多用するなら、その部分は Widget 化します。ん？```Ti.UI.AttributedString``` できないって？いやだなあ、これは Alloy で書けますよ。どこかの誰かがビューとスタイルで書けるようにしてくれたんです（自慢）。

### JSHint、JS Beautifier を忘れない

JSHint はもう当たり前ですね。できることなら JS Beautifier もしちゃいましょう。綺麗なコードを保つ。これ、大事です。

さらに Titanium Style Sheets、これも汚くなりがちです。そこで [tssfmt](https://github.com/k0sukey/tssfmt) をご用意しました。cssfmt みたいなやつですね。その昔、tss-formatter というものがありました（cssfmt よりも前なんですよ！）。fmt って省略するのが流行りっぽいので名前を変えてフルスクラッチしたものです。Alloy に依存しないようにしたりと、内部は別物なんですけどね。
tssfmt はプロパティの順序まで強制することができます。```top``` や ```left``` プロパティがクラスによって順序がバラバラなんて、ストレスでしかありません。こんなところで気を使うくらいなら、別のところで集中したいですもんね。今ならなんと、tssfmt の [gulp プラグイン](https://github.com/k0sukey/gulp-tssfmt) までご提供中です。

### イベント外そう

使い終わったイベント、ちゃんと外していますか？こういう小さな積み重ねも大事なんですよね。おっと、一つ一つ ```removeEventListener``` が面倒ですか？いやいや、便利なメソッドがあるんですよ。```$.removeListener();``` してみてください。ビューに ```onClick``` 等でイベント処理を記述しておけば、対象コントローラの全てのイベントを一括で解除することができます。どこかの誰かが追加したんですね。簡単でしょ？（自慢）

普通に ```addEventListener``` した場合は対象にならないので、気をつけてください。コントローラ内で別途イベントを追加したい場合は、```$.addListener``` メソッドが用意されています。このメソッドを使えば対象になりますので、こちらを使ってください。

## まとめ

文字ばかりになってしまいましたが、24 日はもっと文字が増えると予想されます。テストですからね。カバレッジのスクショくらいは貼り付けて盛り上げたいですね。それでは。