Titanium で Pull-to-Refresh、イベント処理(scroll / dragend)やフラグ管理が面倒ですよね。 最近だと @FokkeZB さん作の nl.fokkezb.pullToRefresh が Alloy の Widget として使えて、ずいぶん便利になってきています。

ただ、やっぱり iOS6 から使える、UIRefreshControl が使いたいところです。 びよーんって伸びて無駄に引っ張りたくなっちゃいます。 Titanium でも使いたくて UIRefreshControl したくてモジュールを書いたりしましたが、iOS6 のみなのがネックでした。

TiISRefreshControl

そこで ISRefreshControl の力を借りてしまおうということです。 これは iOS4 / iOS5 でも UIRefreshControl の様に振る舞ってくれる、素敵なライブラリです。 何としてでも Titanium で使いたいところです。

と、言うわけで、TiISRefreshControl を書きました。 それでは簡単な使い方をご説明します。 このモジュールはソースコード内で require する必要はありません。 tiapp.xml の <module> に記述するだけで Ti.UI.TableView と Ti.UI.ListView に Pull-to-Refresh を提供します。

<modules>
    <module platform="iphone">be.k0suke.tiisrefreshcontrol</module>
</modules>

Ti.UI.TableView を例にしてみましょう。以下のコードだけで簡単に Pull-to-Refresh の挙動を実現することができます。

var tableView = Ti.UI.createTableView({
	data: [
		{ title: 'row0' },
		{ title: 'row1' },
		{ title: 'row2' },
		{ title: 'row3' },
		{ title: 'row4' },
		{ title: 'row5' },
		{ title: 'row6' },
		{ title: 'row7' },
		{ title: 'row8' },
		{ title: 'row9' }
	]
});

tableView.addEventListener('refreshstart', function(){
	setTimeout(function(){
		tableView.refreshFinish();
	}, 5000);
});

では、実際にデータを取得してからの処理はどうでしょうか。 Alloy のデータバインディングとあわせてご覧ください。

View

<Window>
	<ListView id="lists" defaultItemTemplate="list">
		<Templates>
			<ItemTemplate name="list">
				<Label bindId="name" class="name"/>
			</ItemTemplate>
		</Templates>

		<ListSection id="section" dataCollection="lists" dataTransform="doTransform">
			<ListItem template="list" name:text="{name}"/>
		</ListSection>
	</ListView>
</Window>

Controller

var lists = Alloy.Collections.lists;

function doTransform(model) {
	return model.toJSON();
}

$.lists.addEventListener('refreshstart', function(){
	lists.fetch({
		success: function(){
			$.lists.refreshFinish();
		},
		error: function(){
			$.lists.refreshFinish();
		}
	});
});

$.index.addEventListener('open', function(){
	$.lists.refreshBegin();
});

$.index.open();

ウィンドウである $.index を開くと同時に Ti.UI.ListView の refreshBegin メソッドを実行します。 このメソッドは、ListView を引っ張る挙動をコードから実行してくれます。 データの受信が完了したら refreshstart イベントが発火すると lists コレクションのフェッチが実行されます。 データの受信が成功失敗にかかわらずインジケータを消してあげないといけませんので、success / error 両方で refreshFinish メソッドを実行します。

というわけで、簡単に UIRefreshControl を Titanium で使えるようにするモジュールのご紹介でした。 他にも細かなメソッドやイベントがありますので、詳しくは GitHub の README をご覧ください。