これまで、『DelphiアプリケーションをWindows 10対応したついでにiOSとAndroidにも対応してみた』や『アルバムアプリをモバイル対応するためにDelphiサーバーアプリを作成してみる』などで、マルチデバイスアプリケーション開発のクライアント側とサーバー側の双方をDelphiによって作成する方法を見てきました。

Object Pascal言語(C++Builderの場合はC++言語)の単一コードで、Windows、iOS、Android、Mac OS X向けのネイティブアプリが作成できることは魅力ですが、現実のクロスプラットフォームアプリ開発では、アプリが動作するOSごとの違い、特にUXの差が悩みどころです。
ということで、今回はアルバムアプリの進化形を検討しながら、デバイスごとのUXの差にどのように対処していくのかを見ていくことにしましょう。
シンプルさが重要なモバイルアプリ
さて、モバイルデバイス向けのOSといえば、iOSとAndroidが双璧です。「主要なモバイルデバイスに対応する」といえば、必ずこの2つが対象になります。
iOSおよびAndroidのUXガイドライン
いずれのデバイスについても、以下のようなページで、UXのガイドラインが紹介されています。
どちらも限られた操作、画面サイズという環境で、いかに簡単にユーザーが目的を達成できるかという視点を大事にして、シンプルさを強調しています。PC向けのアプリケーション開発の経験をそのままモバイル開発に持ち込むと、多様なユーザーの要求に応えるべく、複雑で多機能、豪華な画面を設計してしまいがちですが、モバイルデバイスでは、ユーザーがアプリに単機能の仕事を求める点に注意すべきです。
OSごとの違い
iOSとAndroidで目を引く大きな違いは、たとえばボタンやスイッチの形状、そしてページタブのレイアウトなどです。

それぞれのOSを利用するユーザーは、そのOSのルック&フィールに慣れていると想定されますから、自分の開発するアプリだけ独自の世界を作ってしまうわけにはいきません(ゲームなど一部の特殊な世界観を演出するアプリは例外です)。
ということで、マルチデバイスアプリ開発では、それぞれのOSごとに異なるルック&フィールに対応する必要があります。Delphiのマルチデバイス開発機能が、これにどのように対応するのか、アルバムアプリの拡張をしながら見ていきましょう。
アプリの基本スタイルを再確認する
モバイルアプリは全画面
さて、その前にモバイルアプリの基本スタイルを確認しておきましょう。モバイルアプリは、全画面で構成され、Windowsアプリケーションのように閉じるボタンはありません。アプリケーションが終了するのは、ユーザーやシステムが強制的に終了させる操作をしたときのみです。
全画面で構成されるため、そのナビゲーションは簡単で共通性がなければなりません。アプリの現在の画面から、別の画面に移行するには、そのOSで共通のスタイルを使う方が親切です。
一般的なiOSアプリの構成は以下のようなかたちです。

一方、Androidアプリは次のようになります。

Androidの「戻る」ボタンはハードボタン
どちらも基本的なイメージは同じですが、小さな、しかし大事な違いもあります。Androidデバイスには、iPhoneやiPadにはない「戻る」ボタンがあります。そのため、アプリ側で戻るボタンを用意する必要がなく、一方、デバイス側のボタン操作によって、アプリ側にボタンの用意がなくても「戻る」操作を要求されることがあります。
アプリの画面遷移をDelphiなりに考える
一方、アプリを作る側の視点で、このようなアプリの画面遷移はどのように実現されるのかも確認しておきましょう。Windowsアプリケーション開発では、設定画面を表示する場合には、ウィンドウをポップアップ表示させるのが常套手段です。
モバイルアプリの画面遷移テクニック
しかし、全画面で構成されるモバイルアプリの場合、方法はひとつではありません。
- パネルを重ねる:全画面で構成されているアプリのウィンドウの上にパネルを重ね、その上に配置されたコントロールで各種設定をさせることができます。この方法では、パネルをアニメーションで移動させたり、背景を透かしたりと、iOSのガイドラインなどで推奨されているUXの実現も容易です。

- 別のウィンドウを表示する:Windowsアプリケーションと同じように画面の遷移を行う場合には、別のウィンドウを表示するという選択もあります。Delphiの場合は、別のフォームを表示する操作になります。この方法は、マルチデバイスアプリの開発者視点としては、Windowsと同様のフォームを使用できるという利点がありますが、一方で、モバイルアプリのUXを損なっていないか、ガイドラインを参照しての検討が必要になります。
- タブなどのコントロールを使用する:ページタブは、複数画面を切り替えるのによく使われる方法です。タブというと従来の発想ではオフィスで見かけるファイリング用品のタブのようなイメージでしたが、最近はさまざまなモダンなスタイルが登場しています。
今回は、最後のタブを使いこんでみたいと思います。
タブを使ってみる
Delphiのよいところは、すぐに画面を設計して、その場で外観を確認できることです。さっそく、タブをiOSとAndroidで使いわけてみましょう。
新規マルチデバイスアプリケーションの作成
マルチデバイスアプリケーションを新規に作成します。テンプレートに「タブ」付きのアプリが用意されているのですが、これを使ってしまうと、タブの構成の仕方を順序立ててみることができないので、あえて空のアプリケーションを選択します。
表示されたフォーム(現在はWindowsのUIになっています)に、TTabControlを配置します。

ご覧のようにコンポーネントはただの四角です。マウスを右クリックすると、[TTabItemの追加]というメニューがあります。これを数回選択すると、複数のタブページが作成されました。

コンポーネントの構成を表示する構造ペイン(上図左上)を見ると、TTabControlの下に、TTabItemがあり、親子関係になっていることが見て取れます。
OSごとの違いを見る
外観が古臭くてどうもテンションが上がらないので、スタイルをWindowsからiOSに変えてみます。

ご覧のように、タブの位置が上ではなく下に変わりました。青い色の文字もiOSっぽいです。せっかくですから、Androidにも変えてみましょう。

OSによってタブの位置が変わるのは、TabPositionプロパティのおかげです。オブジェクトインスペクタで、配置したTTabControlのTabPositionプロパティの値を見ると、PlatformDefaultになっています。この値をたとえば、Bottomに変更すると、Androidでも、タブが下に配置されます。
TTabControlのもうひとつの表示オプション
ところで、TabPositionプロパティには、Dotsというオプションもあります。これを選択すると、次のように画面上にドットが表示され、ホーム画面のように、複数ページをすばやく切り替えて使用するようにできます。

iOSのアイコンがかっこいいタブを作る
「iOSだけアイコン」にするには?
iOSとAndroidでタブのスタイルが異なる点は、その位置だけではありません。iOSの場合、しばしばアイコンが表示されるのに対し、Androidは結構しっかりした文字が表示されています。
iOSだけアイコン表示が推奨されている状況で、別に作り分けが必要なのでしょうか?
実はDelphiには、StyleLookupという便利な機能があり、よく使う機能をアイコンも含めて簡単に選択できます。しかも、OSごとの差はフレームワーク側で処理してくれるので、各OSで最適なクールな表示になります。
StyleLookup
では、早速StyleLookupを使ってみましょう。TabPositionプロパティをPlatformDefaultに戻して、スタイルをiOSに変更してから作業します。
構造ペインでTabItem1(先ほど追加したタブ)を選択します。オブジェクトインスペクタで、StyleLookupの値列をクリックして、ドロップダウンリストを開くと、次のようにさまざまなアイコンと機能を選択できます。

タブの完成
さらにTextプロパティでタブの文字列も修正します。残りのタブにも同様の設定を行って、次のようなかっこいいタブに変更しました。

ただし、これはiOSのみに表示され、他のタブにアイコンを表示しないスタイルのOSでは、引き続き文字だけが表示されます。
タブページの中身を作る
各タブページの中身、つまりコンテンツを用意するのは簡単です。設計画面でそれぞれのタブをクリックするか、構造ペインでTabItemを選択すれば、タブがアクティブになり、その上に任意のコンポーネントを配置できます。
アルバムアプリの構成
例えば、アルバムアプリは次のように3つのページを構成しました。

3番目のページには、TabPositionプロパティをDotsに設定したTTabControlを入れ子にしています。この入れ子になったタブには、お気に入りの写真3点を表示するようにしました。いつでもお気に入りにアクセスでき、スワイプ操作で簡単に次の写真を表示できます(スワイプを行うには、TGestureManagerを配置して、左右のスワイプ操作に対し、タブを切り替えるコードを書きます。アニメーションを加えるには、もう少し高度なテクニックが必要ですが、これについてもコンポーネントが用意されています)。

モバイルアプリの必須アイテム「リスト」
モバイルアプリで一覧表示に便利な「リスト」
モバイルアプリでは、「リスト」をよく使います。ただ、その機能は、Windowsアプリケーションなどで慣れ親しんだリストとはずいぶん違います。
スマートフォンを縦向きで使う場合、データは上下にスクロールしたほうが自然です。横幅に制限がある中で、データを分かりやすく表示するには、リストの項目に複数の情報を表示するようにしたくなるでしょう。
モバイルアプリのリストは、このような発想から進化してきたと想像されます。当然、進化の過程を異にするiOSとAndroidでは、外観が異なります。
iOSとAndroidのリスト
次の図は、iOSとAndroidの典型的なリストです。どちらも同じようにスクロールしますが、外観は少し違います。

Delphiでは、TListViewコンポーネントがこの用途のリストに当たります。Windowsからの流儀でいくと、TListが対応するコンポーネントのような気がするかもしれませんが、TListは、Windows同様、オプション項目を選択するような限られた機能に利用します。
TListViewを使用することで、アルバムアプリにも素敵な一覧機能が付きました。
プラットフォームコントロール
膨大なデータを扱う場合の問題
TListViewをこのような用途に使った場合、ちょっと困った問題が発生します。膨大な量の写真をリスト表示したとき、皆さんはよくスワイプ操作でとても速くスクロールさせて、目的の写真の近くまで移動させようとしませんか?
このようなときに、特にiOSでスクロールのパフォーマンス問題に直面することがあります。Delphiのマルチデバイスアプリケーションは、ネイティブコードで実行されますが、UIコントロールは、独自のレンダリング(GPUネイティブで実装されています)機能を使用します。つまり、外観はOSネイティブのコントロールのように見えますが、実際には、独自描画の機能を使っているのです。
OSネイティブのコントロールを使う
大規模データを扱うリストのように、パフォーマンスにシビアな場面では、ネイティブコントロールでないことによる負荷が悪影響を及ぼします。このような場面のために、Delphiでは、プラットフォームコントロールと呼ばれる機能が用意されています。
プラットフォームコントロールは、同じコンポーネントを使いながら、ControlTypeプロパティを切り替えるだけで、OSネイティブのコントロールに切り替わる機能です。これを用いれば、場面によってOSネイティブの機能を使い分け、パフォーマンスや機能面で満足いくものを提供できます。

プラットフォームコントロールを使うには
プラットフォームコントロールを使う手順は簡単です。コンポーネントを選択して、オブジェクトインスペクタで、ControlTypeプロパティをPlatformに設定するだけです。設計画面の外観は変わりませんが、プラットフォームコントロールであることを示すアイコンが右下に表示されます。

現在プラットフォームコントロールは、iOS、Windowsを中心にサポートされており、TEdit、TListView、TMemo、TSwitch、TCalendarといったコンポーネントで利用できます。
Delphiのマルチデバイス開発ではデバイス固有の最適化も可能
デバイスごとの細かいチューニング要求に応えるには
OSごとのUXを自動的に最適化してくれるコンポーネントを活用することで、ガイドラインに沿った分かりやすいアプリを作成することができます。とはいえ、ときとしてOSやデバイスごとに特別なチューニングやカスタマイズをしたくなるものです。
特別なことをしたくなった瞬間に、これまでの利便性が失われるのは、この種のビジュアルツールによくあることなのですが、Delphiの場合、そのようなことはありません。FireUIマルチデバイスデザイナは、各デバイスごとの最適化をマスターフォームとの継承関係によって実現したツールです。マスターでの変更は、継承したデバイスごとのUIにも反映される一方、デバイス固有のUIに対する変更は、そのフォームだけにとどまります。

これらの機能を活用すれば、効率的にいろいろなデバイス向けに最適なアプリを構築できるでしょう。
マルチデバイス開発ツール Delphi / C++Builder / RAD Studio
ここで紹介した機能は、C++言語によってもすべて利用でき、C++BuilderまたはRAD Studioとして販売されています。最新バージョンは、Windows 10にも対応しており、バージョン番号はWindows 10にちなんで、10 Seattleと命名されています。
詳しくは、以下の情報をご確認ください。
Delphi/C++Builder/RAD Studio 10 Seattleは、「翔泳社 SEshop」でお求めいただけます。現在、ポイントアップなど、お得なキャンペーンを実施しています。